我想在tableview的每个单元格上显示倒数计时器。
步骤
我有来自服务器的优惠清单,有过期时间。所以在那之后我想用UITableView上的每个单元显示这个过期倒数计时器。
我正在做这样的事情。 但没有结果。
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! TimeCell
cell.expiryTimeInterval = 2
return cell
}
**我的Cell Class,我正在启动计时器。印刷Step1&仅限步骤2 **
class TimeCell: UITableViewCell {
@IBOutlet weak var myLabel: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
private var timer: Timer?
private var timeCounter: Double = 0
var expiryTimeInterval : TimeInterval? {
didSet {
startTimer()
print("Step 1 \(expiryTimeInterval!)")
}
}
private func startTimer() {
if let interval = expiryTimeInterval {
timeCounter = interval
print("Step 2 \(interval)")
if #available(iOS 10.0, *) {
timer = Timer(timeInterval: 1.0,
repeats: true,
block: { [weak self] _ in
guard let strongSelf = self else {
return
}
strongSelf.onComplete()
})
} else {
timer = Timer(timeInterval: 1,
target: self,
selector: #selector(onComplete),
userInfo: nil,
repeats: true)
}
}
}
@objc func onComplete() {
print("Step 3")
guard timeCounter >= 0 else {
timer?.invalidate()
timer = nil
return
}
myLabel.text = String(format: "%d", timeCounter)
timeCounter -= 1
}
}
答案 0 :(得分:4)
我建议你创建一个自定义单元格,在该单元类中,根据服务器的值创建一个计时器。这样每个单元都有自己的计时器。这就是你可能想要的。 在当前的实现中,您的计时器处理程序不知道单元格或其行号。
class MyCustomCell: UITableViewCell {
@IBOutlet weak private var myLabel: UILabel!
private var timer: Timer?
private var timeCounter: Double = 0
var expiryTimeInterval: TimeInterval? {
didSet {
startTimer()
}
}
private func startTimer() {
if let interval = expiryTimeInterval {
timeCounter = interval
if #available(iOS 10.0, *) {
timer = Timer(timeInterval: 1.0,
repeats: true,
block: { [weak self] _ in
guard let strongSelf = self else {
return
}
strongSelf.onComplete()
})
} else {
timer = Timer(timeInterval: 1.0,
target: self,
selector: #selector(onComplete),
userInfo: nil,
repeats: true)
}
}
}
@objc func onComplete() {
guard timeCounter >= 0 else {
timer?.invalidate()
timer = nil
return
}
myLabel.text = String(format: "%d", timeCounter)
timeCounter -= 1
}
}
<强>用法强>
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! MyCustomCell
cell.expiryTimeInterval = 10
return cell
}
转到您的单元格nib
或storyboard
,并将TimeCell
的班级名称更改为MyCustomCell
答案 1 :(得分:1)
@Umair Aamir我实施了您的解决方案,并且它正常工作,但是,下一行代码至关重要,因此每次滚动时都不会初始化计时器...
仅仅检查if timer == nil
override func prepareForReuse() {
super.prepareForReuse()
timer?.invalidate()
timer = nil
}
您应该在您的单元格子类中添加它。 希望它有所帮助!
答案 2 :(得分:-1)
import UIKit
class CompetitionTableViewCell: UITableViewCell {
//MARK:- IBOutlets
@IBOutlet weak var mainView: UIView!
@IBOutlet weak var imageCompetition: UIImageView!
@IBOutlet weak var btnStart: UIButton!
@IBOutlet weak var lblTime: UILabel!
@IBOutlet weak var lblCompititor: UILabel!
@IBOutlet weak var lblPoints: UILabel!
@IBOutlet weak var lblNameCompetition: UILabel!
@IBOutlet weak var btnGoForTest: UIButton!
//MARK:- Variable
private var timer: Timer?
private var timeCounter: Double = 0
//MARK:- IBActions
var expiryTimeInterval: TimeInterval? {
didSet {
if timer == nil
{
startTimer()
RunLoop.current.add(timer!, forMode: .commonModes)
}
}
}
private func startTimer() {
if let interval = expiryTimeInterval {
timeCounter = interval
if #available(iOS 10.0, *) {
timer = Timer(timeInterval: 1.0,
repeats: true,
block: { [weak self] _ in
guard let strongSelf = self else {
return
}
strongSelf.onComplete()
})
} else {
timer = Timer(timeInterval: 1.0,
target: self,
selector: #selector(onComplete),
userInfo: nil,
repeats: true)
}
}
}
@objc func onComplete() {
guard timeCounter >= 0 else {
btnGoForTest.isUserInteractionEnabled = false
lblTime.text = "Time ended."
timer?.invalidate()
timer = nil
return
}
btnGoForTest.isUserInteractionEnabled = true
let hours = Int(timeCounter) / 3600
let minutes = Int(timeCounter) / 60 % 60
let seconds = Int(timeCounter) % 60
lblTime.text = String(format:"%02i:%02i:%02i", hours, minutes, seconds)
timeCounter -= 1
print("\(timeCounter)")
}
override func awakeFromNib() {
super.awakeFromNib()
btnStart.setCornerRadiusForBtn()
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
override func prepareForReuse() {
super.prepareForReuse()
timer?.invalidate()
timer = nil
}
}
/***** code for your listing tableview ***************/
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CompetitionTableViewCell") as! CompetitionTableViewCell
cell.btnGoForTest.tag = indexPath.row
cell.lblTime.tag = indexPath.row
//cell.lblTime.tag = indexPath.row
let dicttemp : Dictionary = arrAllCoursesList[indexPath.row] as! Dictionary<String,Any>
if let getTime = dicttemp["endtime"] as? Int
{
cell.lblTime.text = ""
let getTime1 : Double = Double(getTime)
cell.expiryTimeInterval = getTime1
}
return cell
}