UITableViewCell 中的多个计时器 (Swift)

Multiple timers in UITableViewCell (Swift)

我有 UITableViewcells 是在不同的时间创建的,我希望它们中的每一个都有一个独立的计时器,当对象被添加 reloadData()[=15= 时触发]

这是我目前所做的

import UIKit

var timer = Timer()
var blinkStatus:Bool! = false
var time = 300


class LiveViewCell: UITableViewCell {

    let str = String(format:"%02d:%02d", (time / 60), (time % 100))
    func processTimer() {

        if time > 0 {
            time -= 1
            timeRemainingLbl.text = String(time)
        } else if time == 0 {
            timer.invalidate()
            timeRemainingLbl.text = "Due!"
            timer = Timer.scheduledTimer(timeInterval: 0.5, target: self, selector: #selector(LiveViewCell.blinkTimer), userInfo: nil, repeats: true)

        }

    }

    func blinkTimer() {
        if blinkStatus == false {
            timeRemainingLbl.textColor = UIColor(red:1.00, green:0.00, blue:0.00, alpha:1.0)
            blinkStatus = true
        } else if blinkStatus == true {
            timeRemainingLbl.textColor = UIColor.clear
            blinkStatus = false
        }

    }


    @IBOutlet weak var tableNumberLeftLabel: UILabel!
    @IBOutlet weak var guestNumbersLabel: UILabel!

    @IBOutlet weak var timeInTableLabel: UILabel!
    @IBOutlet weak var tableNumberLbl: UILabel!
    @IBOutlet weak var timeRemainingLbl: UILabel!


    var table: Table!


    func configureLiveCell(_ NT: Table) {

        layer.cornerRadius = 20
        timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(LiveViewCell.processTimer), userInfo: nil, repeats: true)
        tableNumberLbl.text = "T" + String(NT.number)
        timeRemainingLbl.text = String(time)

    }
}

每当我创建一个新单元格时调用 configureLiveCell 时就会出现问题。计时器似乎在加速,我希望每个计时器都是独立的。

覆盖 prepareForReuse 方法。

override func prepareForReuse() {
    super.prepareForReuse()

    timer.invalidate()
}

这将在单元格返回以供另一行使用之前调用。通过在此处使计时器无效,您的 configureLiveCell 不会创建另一个计时器。

顺便说一句 - 你还应该添加一个 deinit 方法并在那里也使计时器无效。

您还使 timer 属性 可选,并在使它无效后将其设置为 nil。当然你需要添加适当的检查来处理它是一个可选的。

您必须做的最后一项更改是更改 timertimeblinkStatus,通过将它们移动到 class 中,使它们成为实例变量。

这是在 swift 2.0

的 UITableview Cell 中管理计时器的代码

IN ViewController

class ViewController: UIViewController, UITableViewDelegate , UITableViewDataSource{

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

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

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

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("TblCell", forIndexPath: indexPath) as! TblCell

        cell.selectionStyle = .None
        return cell
    }

    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        let cell : TblCell = (tableView.cellForRowAtIndexPath(indexPath) as? TblCell)!
        cell.setupTimer(with: indexPath.row)
    }
}

IN UITableviewCell

class TblCell: UITableViewCell {
    @IBOutlet weak var lblTimer: UILabel!

    var couponTimer : NSTimer?
    var startTime : NSDate!
    var currentIndex : Int = 1

    func setupTimer(`with` indexPath: Int){
        currentIndex = indexPath + 1

        self.startTime = NSDate()

        if self.couponTimer != nil {
            self.couponTimer?.invalidate()
            self.couponTimer = nil
        }

        couponTimer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: #selector(self.calculateTime), userInfo: nil, repeats: true);

        NSRunLoop.currentRunLoop().addTimer(couponTimer!, forMode: NSRunLoopCommonModes)
        couponTimer?.fire()
    }

    func stopTimer(){
        if self.couponTimer != nil {
            self.couponTimer?.invalidate()
            self.couponTimer = nil
        }
    }

    func calculateTime() {
        let dateFormatter = NSDateFormatter()
        dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"

        let dateFormatter1 = NSDateFormatter()
        dateFormatter1.dateFormat = "yyyy-MM-dd"

        let tomorrow = NSCalendar.currentCalendar()
            .dateByAddingUnit(
                .Day,
                value: currentIndex,
                toDate: NSDate(),
                options: []
        )

        let tomorrowDate = dateFormatter1.stringFromDate(tomorrow!)
        let tomorrowActiveDate = dateFormatter.dateFromString(tomorrowDate + " " + "10:15:00")

        let currentDate   = NSDate()

        let strTimer : String = tomorrowActiveDate!.offsetFrom(currentDate)
        self.lblTimer.text = strTimer
        self.lblTimer.textColor = UIColor.whiteColor()
        self.lblTimer.backgroundColor = UIColor(red: 255.0/255.0, green: 44.0/255.0, blue: 86.0/255.0, alpha: 1.0)
    }
}

分机

extension NSDate {

    func offsetFrom(date:NSDate) -> String {

        let dayHourMinuteSecond: NSCalendarUnit = [.Day, .Hour, .Minute, .Second]
        let difference = NSCalendar.currentCalendar().components(dayHourMinuteSecond, fromDate: date, toDate: self, options: [])

        var seconds : String = ""
        var minutes : String = ""
        var hours : String = ""
        var days : String = ""

        let tmp1 : String = String(format: "%.2d", difference.second)
        let tmp2 : String = String(format: "%.2d", difference.minute)
        let tmp3 : String = String(format: "%.2d", difference.hour)
        let tmp4 : String = String(format: "%d", difference.day)

        seconds = "\(tmp1)"
        minutes = "\(tmp2)" + ":" + seconds
        hours = "\(tmp3)" + ":" + minutes
        days = "\(tmp4)d" + " " + hours

        if difference.second >= 0 && difference.minute >= 0 && difference.hour >= 0 && difference.day >= 0 {
            return days
        }
        else {
            return ""
        }
    }
}