我想在表格视图的每个单元格上显示倒数计时器。
步骤
我有来自服务器的报价列表,有过期时间。所以在那之后,我想在 UITableView 上显示这个过期倒数计时器的每个单元格。
我正在做这样的事情。但没有结果。
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! TimeCell
cell.expiryTimeInterval = 2
return cell
}
**我的细胞类,我正在启动计时器。仅打印步骤 1 和步骤 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
}
}
我宁愿建议您创建一个自定义单元格,并在该单元格类中,根据来自服务器的值创建一个计时器。这样,每个单元格都有自己的计时器。这就是你可能想要的。在当前实现中,计时器处理程序不知道单元格或其行号。
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
@Umair 阿米尔 我实现了您的解决方案,它工作正常,但是,接下来的代码行至关重要,因此每次滚动时都不会初始化计时器...
检查if timer == nil
是不够的
override func prepareForReuse() {
super.prepareForReuse()
timer?.invalidate()
timer = nil
}
您应该将其添加到单元格子类中。希望对您有所帮助!
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
}