【问题标题】:Delete NSTimer/UITableViewCell in real time?实时删除NSTimer/UITableViewCell?
【发布时间】:2015-07-14 13:42:11
【问题描述】:

我有一个UITableView,其中我在每个UITableViewCell 上设置了许多计时器。每个计时器从用户在我的应用程序上创建“帖子”开始,并应在 24 小时内到期。但是,我希望它在所有 24 小时结束后,UITableViewCell 会实时删除自己,但我似乎无法弄清楚我应该在何时何地删除计时器。我有一种方法可以每秒使用NSTimer.scheduledTimerWithTimeInterval 不断刷新计时器,并且每秒更新每个UITableViewCell 上的计时器。但是,我找不到方法或找不到每个 UITableViewCell 中的每个计时器是否已完成的方法。显然,我可以找到计时器是否在viewDidLoad 中完成,但这仅在视图变为活动状态时才被调用。是否有任何我遗漏的方法或任何我可以用来查找通过 scheduledTimerWithTimeInterval 方法的计时器是否完成的方法,如果是,删除它?下面是我的代码:

//I have a self.offers array declared in the beginning of my class whcih will act as the UITableView data source.
var offers = [Offer]()


func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    //Dequeue a "reusable" cell
    let cell = tableView.dequeueReusableCellWithIdentifier(offerCellIdentifier) as! OfferCell
    setCellContents(cell, indexPath: indexPath)
    return cell
}

func setCellContents(cell:OfferCell, indexPath: NSIndexPath!){
    let item = self.offers[indexPath.row]
    cell.offerName.text = item.offerName()
    cell.offerPoster.text = item.offerPoster()

    var expirDate: NSTimeInterval = item.dateExpired()!.doubleValue

    //Get current time and subtract it by the predicted expiration date of the cell. Subtract them to get the countdown timer.
    var timeUntilEnd = expirDate - NSDate().timeIntervalSince1970

    if timeUntilEnd <= 0 {
        //Here is where I want to delete the countdown timer but it gets difficult to do so when you are also inserting UITableViewCells and deleting them at the same time.
        self.offers.removeAtIndex(indexPath!.row)

        self.offersReference = Firebase(url:"<Database Link>")
        self.offersReference.removeValue()
        self.tableView.reloadData()
        cell.timeLeft.text = "Finished."
    }
    else{
        //Display the time left
        var seconds = timeUntilEnd % 60
        var minutes = (timeUntilEnd / 60) % 60
        var hours = timeUntilEnd / 3600

        cell.timeLeft.text = NSString(format: "%dh %dm %ds", Int(hours), Int(minutes), Int(seconds)) as String
    }
}

override func viewDidLoad() {
    super.viewDidLoad()
    var timeExpired = false
    //I set up my offers array above with completion handler
    setupOffers { (result, offer) -> Void in
        if(result == true){
            //Insert each row one by one.
            var currentCount = self.offers.count
            var indexPaths: [NSIndexPath] = [NSIndexPath]()
            indexPaths.append(NSIndexPath(forRow:currentCount, inSection: 0))
            self.offers.append(offer)
            currentCount++
            self.tableView.reloadData()
        }
    }
    // Do any additional setup after loading the view, typically from a nib.
    self.tableView.delegate = self
    self.tableView.dataSource = self
    self.tableView.rowHeight = UITableViewAutomaticDimension
    self.tableView.rowHeight = 145.0
}

//Called when you click on the tab
override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)
    self.refreshTimer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: "refreshView:", userInfo: nil, repeats: true)
    //Should fire while scrolling, so we need to add the timer manually:
    //var currentRunLoop = NSRunLoop()
    //currentRunLoop.addTimer(refreshTimer, forMode: NSRunLoopCommonModes)
}

override func viewDidDisappear(animated: Bool) {
    super.viewDidDisappear(animated)
    refreshTimer.invalidate()
    refreshTimer = nil
}

//Constantly refreshes the data in the offers array so that the time will continuously be updating every second on the screen.
func refreshView(timer: NSTimer){
    self.tableView.reloadData()
}

【问题讨论】:

    标签: ios uitableview swift timer nstimer


    【解决方案1】:

    你有一些误解,你的代码有一些问题,你的描述不清楚。

    如果您使用 scheduleTimerWithTimeInterval 创建计时器,则不需要也不应该将其添加到运行循环中。 scheduledTimerWithTimeInterval 方法可以为您做到这一点。

    如果您创建一个重复计时器,它永远不会“结束”。它永远重复。相反,如果您创建一个非重复计时器,它会触发一次然后消失。你不需要删除它。只是不要保持对它的强引用,一旦它触发它就会被释放。

    您说您为每个表格视图单元格创建了一个计时器,但您发布的代码只为视图控制器创建了一个计时器。你说“......它每秒更新每个 UITableViewCell 上的计时器。但是,如果每个 UITableViewCell 中的每个计时器都已完成,我找不到方法或找到如何找到。”这与您发布的代码不匹配。您的代码每秒运行一次计时器,它只是告诉表视图重新加载它的数据。

    我猜你的意思是当你的计时器触发时,你会在每个单元格中重新显示一个剩余时间计数器?

    那么,您是在问如何确定所有单元格的 item.timeLeft() 的剩余时间是否已为零?您尚未发布 timeLeft() 函数的代码或要求,因此您的读者无法判断应该发生什么。

    【讨论】:

    • 您好,感谢您让我了解 runloop。我会相应地解决这个问题。关于重复计时器,我想让它重复,因为我希望它实时更新计时器。如果我将scheduledTimerWithTimeInterval 中的repeat: 参数设置为false,计时器将不会实时更新。我为问题的最后一部分道歉,因为我不想发布太多代码,所以我非常草率。我会相应地对其进行编辑并尝试使事情更清楚。
    • 我已经在上面发布了我的编辑。我删除了一些误导性代码并展示了我的UITableViewCells 是如何工作的。我为之前道歉。所以基本上我想做的是当timeLeft()变为0时,我想实时从UITableView中删除该单元格。但是,我意识到在setCellContents 中执行此操作并不是最好的方法,因为我在插入我的tableView 时也会调用此方法,所以我会遇到冲突。我想知道是否有一种方法可以找到每个单元格的计时器何时达到 0,然后完全删除该单元格。
    • 没关系,我都修好了。上面的代码有效。感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 2011-08-17
    • 2015-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-12
    • 2023-03-27
    • 1970-01-01
    相关资源
    最近更新 更多