iOS中UITableView每个单元格的时间倒计时
我想在tableview的每个单元格上显示倒计时计时器 步骤 我有来自服务器的过期时间的报价列表。然后我想在UITableView上用每个单元格显示这个过期倒计时计时器 我正在做这样的事情。 但没有结果iOS中UITableView每个单元格的时间倒计时,ios,swift,uitableview,Ios,Swift,Uitableview,我想在tableview的每个单元格上显示倒计时计时器 步骤 我有来自服务器的过期时间的报价列表。然后我想在UITableView上用每个单元格显示这个过期倒计时计时器 我正在做这样的事情。 但没有结果 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableC
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
}
转到你的cell
nib
或storyboard
,将TimeCell
的类名更改为MyCustomCell@Umair Aamir我实现了你的解决方案,它工作正常,但是,下一行代码很关键,所以每次滚动时计时器都不会初始化
如果计时器=nil,则仅检查是不够的
override func prepareForReuse() {
super.prepareForReuse()
timer?.invalidate()
timer = nil
}
您应该将其添加到您的cell子类中。
希望有帮助 导入UIKit
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
}
类CompetitionTableViewCell:UITableViewCell{
//标记:-IB出口
@IBVAR主视图:UIView!
@IBVAR弱图像竞争:UIImageView!
@IBOUTLE弱var btnStart:UIButton!
@IBOutlet弱变量lblTime:UILabel!
@IBOUTLE弱变量LBLCOMPITOR:UILabel!
@IBOutlet弱var lblPoints:UILabel!
@IBOutlet弱var lblNameCompetition:UILabel!
@IBOUTLE弱var btnGoForTest:UIButton!
//标记:-变量
私有变量计时器:计时器?
专用变量计时器:双精度=0
//标记:-IBActions
var expiryTimeInterval:时间间隔{
迪塞特{
如果计时器==nil
{
startTimer()
RunLoop.current.add(timer!,forMode:.commonModes)
}
}
}
私有函数startTimer(){
如果let interval=expiryTimeInterval{
计时器=时间间隔
如果可用(iOS 10.0,*){
计时器=计时器(时间间隔:1.0,
重复:是的,
块:{[弱自]\uuIn
守卫让strongSelf=self-else{
返回
}
strongSelf.onComplete()
})
}否则{
计时器=计时器(时间间隔:1.0,
目标:自我,
选择器:#选择器(未完成),
userInfo:nil,
重复:正确)
}
}
}
@objc func onComplete(){
防护计时器>=0{
btnGoForTest.isUserInteractionEnabled=false
lblTime.text=“时间结束。”
计时器?.invalidate()
计时器=零
返回
}
btnGoForTest.isUserInteractionEnabled=true
设小时数=整数(计时器)/3600
分钟数=整数(计时器)/60%60
设秒=Int(计时器)%60
lblTime.text=字符串(格式:“%02i:%02i:%02i”、小时、分钟、秒)
计时器-=1
打印(“\(计时器)”)
}
重写func awakeFromNib(){
super.awakeFromNib()
btnStart.setCornerRadiusForBtn()
}
覆盖功能设置选定(uSelected:Bool,动画:Bool){
super.setSelected(选定,动画:动画)
}
重写func prepareForReuse()函数{
super.prepareforeuse()
计时器?.invalidate()
计时器=零
}
}
/*****清单tableview的代码***************/
func tableView(tableView:UITableView,cellForRowAt indexath:indexPath)->UITableViewCell{
将cell=tableView.dequeueReusableCell(标识符为:“CompetitionTableViewCell”)设为!CompetitionTableViewCell
cell.btnGoForTest.tag=indexPath.row
cell.lblTime.tag=indexPath.row
//cell.lblTime.tag=indexPath.row
让dicttemp:Dictionary=arallcourseslist[indexPath.row]作为!Dictionary
如果让getTime=dicttemp[“endtime”]as?Int
{
cell.lblTime.text=“”
让getTime1:Double=Double(getTime)
cell.expiryTimeInterval=getTime1
}
返回单元
}
当然,现在在我的答案中添加了代码。希望对你有帮助。。谢谢你。但是现在如何在我的UITableVC类中使用这个函数呢?好的!但是在不调用中完成:(这很奇怪。应该被调用。我在代码中这样做。它应该在每秒钟后被调用。是的onStartTimer()正在调用。