Diego Petrucci
Diego Petrucci

Reputation: 221

How do I compute total of values in UITableView cells?

I'm using NSFetchedResultsController with a UITableView. I have a list of "expenses" that gets saved to CoreData. This is as usual. NSFetchedResultsController handles everything as it should.

Every Expense entity has a .amount value (Double).

At the top of a tableview there's a label that shows the totalDebt. totalDebt is just every expense .amount added together (could be positive, negative, or zero).

The app lets you add or delete an item (so a cell, so an entity).

How should I compute the value for the totalDebtLabel?

I tried putting a refreshTotalDebtLabel() in cellForRowAtIndexPath but every time the table reloads every cell is computed, even cells that were already computed. I tried other solutions but they all seem to fail.

Upvotes: 0

Views: 1375

Answers (2)

Mundi
Mundi

Reputation: 80273

The way to do this is to create a refreshLabel method to be called whenever the data changes. You can catch that in various ways, e.g. in the NSFetchedResultsControllerDelegate methods, or when a text field or editing controller returns.

In the refresh method, leverage key-value-coding (KVC) to make it really simple.

let sum = fetchedResultsController.fetchedObjects.valueForKeyPath("@sum.amount") as! Double
// populate the label with the sum

If you are using primitives (such as Double) in your managed object subclass, you might have to refactor with NSNumber which is guaranteed to work and will also reliably hold your Double values. (In this case use ...as! NSNumber).

Upvotes: 2

Nishant
Nishant

Reputation: 12617

You cannot do this inside the table methods. You will have to calculate the totalDebt outside cellForRowAtIndexPath. For example, just after you fetch the array of expenses, you can use a loop to calculate the totalDebt and set it in the label.

func refreshTotalDebtLabel()
{
    let expenses = NSArray() //fetched from core data
    let totalDebt : CGFloat = 0

    expenses.enumerateObjectsUsingBlock { (expenseObj, index, stop) -> Void in
        totalDebt += expenseObj.amount
    }

    print("Total Debt = %f", totalDebt)

    self.totalDebtLabel.text = String("$ %0.2f", totalDebt)
}

Upvotes: 1

Related Questions