NOTE: Asking for answers in Swift please.
What I'm trying to do:
- Have tableview cells update every 1 second and display a real-time countdown.
How I'm doing it currently:
I have a tableview with cells that contain a label.
When the cells are generated, they call a function that calculates the time between today and a stored target date, and it displays the countdown time remaining in the label.
To get the cells to update the label every second, I use an
NSTimer
that reloads the tableview every second.PROBLEM: The countdown works, but when I try to do a Swipe-to-Delete action, because the
NSTimer
reloads the tableview, it resets the swiped cell so that it is no longer swiped and of course this is not acceptable for end users.
What I'm trying / Potential Solutions
I heard that a better way to do this is to use
NSNotificationCenter
that is triggered byNSTimer
and add listeners to each cell. Every 1 second a "broadcast" is sent from theNSNotificationCenter
, the cell will receive the "broadcast" and will update the label.I tried adding a listener to each cell in the part of the code where it generates a new cell:
// Generate the cells override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { var cell = tableView.dequeueReusableCellWithIdentifier("Tablecell", forIndexPath: indexPath) as UITableViewCell let countdownEntry = fetchedResultController.objectAtIndexPath(indexPath) as CountdownEntry // MARK: addObserver to "listen" for broadcasts NSNotificationCenter.defaultCenter().addObserver(self, selector: "updateCountdownLabel", name: mySpecialNotificationKey, object: nil) func updateCountdownLabel() { println("broadcast received in cell") if let actualLabelCountdown = labelCountdown { // calculate time between stored date to today's date var countdownValue = CountdownEngine.timeBetweenDatesRealTime(countdownEntry.date) actualLabelCountdown.text = countdownValue } }
but the observer's selector only seems to be able to target functions at the view controller level, not in the cell. (I can't get "updateCountdownLabel" to fire from within the cell. When I create a function of the same name at view controller level, the function can be called)
Questions
- So my question is: Is this is the right approach?
- If yes, how can I get the listener to fire a function at the cell level?
- If no, then what is the best way to achieve this real-time countdown without interrupting Swipe on Cell actions?
Thanks in advance for your help!