Несколько таймеров в UITableViewCell (Swift)
У меня есть UITableViewcells
, которые создаются в разные моменты времени, и я хотел бы, чтобы каждый из них имел независимый таймер, который срабатывает, когда объект добавляется с reloadData()
Это то, что я сделал до сих пор
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
вызывается всякий раз, когда я создаю новую ячейку. Таймер, кажется, ускоряется, и я хотел бы, чтобы каждый таймер был независимым.
2 ответа:
Переопределите метод
prepareForReuse
.override func prepareForReuse() { super.prepareForReuse() timer.invalidate() }
Это будет вызвано непосредственно перед возвращением ячейки для использования другой строкой. Делая недействительным таймер здесь, Ваш
configureLiveCell
не создает еще один таймер.Кстати-вы также должны добавить метод
deinit
и сделать недействительным таймер там тоже.Вы также делаете СВОЙСТВО
timer
необязательным и устанавливаете его вnil
после того, как вы его аннулируете. И, конечно, вам нужно добавить соответствующие проверки, чтобы иметь дело с тем, что это необязательно.И один последнее изменение, которое вы должны сделать, это изменить
timer
,time
, иblinkStatus
таким образом, они являются переменными экземпляра, перемещая их внутри класса.
Вот код для управления таймером в ячейке UITableview в swift 2.0
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) } }
В 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 "" } } }