learning_swift
learning_swift

Reputation: 107

How to update UITableViewCells using NSTimer and NSNotificationCentre in Swift

NOTE: Asking for answers in Swift please.

What I'm trying to do:

How I'm doing it currently:

What I'm trying / Potential Solutions

Questions

Thanks in advance for your help!

Upvotes: 8

Views: 6397

Answers (2)

Matteo Piombo
Matteo Piombo

Reputation: 6726

It might be a solution not reloading cells at all. Just make the cells listen to an update notification and change their label accordingly. I assume you subclass UITableViewCell and give the cell a storedDate property. You will set that property when preparing the cell.

The timer will just fire the notification.

Remember to unregister the cell from notification center in dealloc

Here is a quick an dirty example.

The View Controller containing your TableView:

class ViewController: UIViewController, UITableViewDataSource {

    @IBOutlet weak var tableView: UITableView!

    var timer: NSTimer!


    //MARK: UI Updates

    func fireCellsUpdate() {
        let notification = NSNotification(name: "CustomCellUpdate", object: nil)
        NSNotificationCenter.defaultCenter().postNotification(notification)
    }

    //MARK: UITableView Data Source

    func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 10
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cellIdentifier = "CustomCell"
        let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier) as! CustomTableViewCell
        cell.timeInterval = 20
        return cell
    }

    //MARK: View Lifecycle
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        self.timer = NSTimer(timeInterval: 1.0, target: self, selector: Selector("fireCellsUpdate"), userInfo: nil, repeats: true)
        NSRunLoop.currentRunLoop().addTimer(self.timer, forMode: NSRunLoopCommonModes)
    }


    deinit {
        self.timer?.invalidate()
        self.timer = nil
    }

}

The custom cell subclass:

class CustomTableViewCell: UITableViewCell {

    @IBOutlet weak var label: UILabel!

    var timeInterval: NSTimeInterval = 0 {
        didSet {
            self.label.text = "\(timeInterval)"
        }
    }

    //MARK: UI Updates

    func updateUI() {
        if self.timeInterval > 0 {
            --self.timeInterval
        }
    }

    //MARK: Lifecycle

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code

        let notificationCenter = NSNotificationCenter.defaultCenter()
        notificationCenter.addObserver(self, selector: Selector("updateUI"), name: "CustomCellUpdate", object: nil)
    }

    deinit {
        NSNotificationCenter.defaultCenter().removeObserver(self)
    }

}

I'm pretty sure this example doesn't adhere to your app's logic. Just showing how things are glowed together.

Upvotes: 15

Raj
Raj

Reputation: 346

As Ian MacDonald has suggested you should avoid reloading the cell when the timer ticks, if you are swiping. Also drop the NSNotification, as It and timer are essentially doing the samething

Upvotes: 1

Related Questions