Swift中使用NSTimer和NSNotificationCe

Swift中使用NSTimer和NSNotificationCe

本文介绍了如何在Swift中使用NSTimer和NSNotificationCentre更新UITableViewCells的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

注意:请在 Swift 中寻求答案。

NOTE: Asking for answers in Swift please.

我正在尝试做什么:


  • 让tableview单元每1秒更新一次并显示实时的
    倒计时。

我目前的表现如何:


  • 我有一个包含标签的单元格的tableview。

  • 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.

为了让细胞每秒更新标签,I
使用 NSTimer 每秒重新加载tableview。

To get the cells to update the label every second, Iuse an NSTimer that reloads the tableview every second.

问题:倒计时有效,但当我尝试执行刷卡到删除操作时,因为 NSTimer 重新加载tableview,它会重置
刷过的单元格,以便不再刷卡,当然这对最终用户来说是不可接受的。

PROBLEM: The countdown works, but when I try to do a Swipe-to-Delete action, because the NSTimer reloads the tableview, it resets theswiped cell so that it is no longer swiped and of course this is not acceptable for end users.

我正在尝试/潜在的解决方案


  • 我听说更好的方法是使用由 NSTimer NSNotificationCenter $ c>并为每个单元格添加侦听器。每隔1秒从 NSNotificationCenter 发送广播,该小区将收到广播并将更新标签。

  • I heard that a better way to do this is to use NSNotificationCenter that is triggered by NSTimer and add listeners to each cell. Every 1 second a "broadcast" is sent from the NSNotificationCenter, 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
    }
}


  • 但是观察者的选择器似乎只能在视图控制器级别而不是在单元格中定位函数。 (我不能从单元格中触发updateCountdownLabel。当我在视图控制器级别创建一个同名函数时,可以调用该函数)

  • 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)

    问题


    • 所以我的问题是:这是是正确的方法吗?

    • 如果是,我如何让监听器在单元级别触发一个函数?

    • 如果不是,那么最好的方法是什么?实现这个实时倒计时而不中断Swipe on Cell动作?

    预先感谢您的帮助!

    推荐答案

    这可能是一个根本不重新加载单元格的解决方案。只需让单元格听取更新通知并相应地更改其标签。
    我假设您将 UITableViewCell 子类化,并为该单元格提供 storedDate 属性。您将在准备单元格时设置该属性。

    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.

    计时器只会触发通知。

    请记住从 dealloc

    中的通知中心取消注册单元格这是一个快速的例子。

    Here is a quick an dirty example.

    包含TableView的View Controller:

    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
        }
    
    }
    

    自定义单元格子类:

    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.

    这篇关于如何在Swift中使用NSTimer和NSNotificationCentre更新UITableViewCells的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

  • 08-14 17:47