【发布时间】:2019-11-21 09:38:05
【问题描述】:
我有一个带有基本 cellforrow 功能的表格视图。我还为我的待办事项列表应用程序构建了一个计时器功能。
我正在尝试使用标准字幕单元格创建一个在 tableview 的每个单元格中都有一个正在运行的倒数计时器的应用程序。计时器名称显示在文本字段中,正在运行的计时器显示在副标题中。
这里的想法是在用户为所选任务设置特定截止日期时计算任务的剩余时间。
我成功地实现了这个功能,但我遇到的问题是,当我将单元格(字幕)的 detailtextlabel 设置为剩余的剩余时间(显示剩余天数/小时/分钟/秒)时,它不会刷新。
总而言之,我想创建一个任务的倒数计时器功能,以显示它每秒倒数。我希望它在 viewdidload 上加载。
我的计时器正确吗?或在错误的地方。我认为如果它是 inn cellforRow 函数,让计时器刷新整个表格是有意义的。
我在 cellforrow 函数中尝试了一个计时器,但没有任何乐趣。然后,我为计时器创建了一个单独的函数,以在其中使用 reloadData() 刷新 tableview。该函数在 viewDidLoad 中调用。倒计时,一切正常,但我的标签不会更新,除非我单击单元格或添加新的待办事项。
override func viewDidLoad() {
super.viewDidLoad()
func startTimer() {
self.countDownTimer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(reloadTableForTimer), userInfo: nil, repeats: true)
}
}
@objc func reloadTableForTimer() {
DispatchQueue.main.async { self.tableView.reloadData() }
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
if item.done == true {
cell.detailTextLabel?.text = "Complete!"
}else {
var deadlineDatesAll = item.deadlineDate
if deadlineDatesAll == "" {
cell.detailTextLabel?.text = "NO DEADLINE SET"
} else {
// insert code for data disection and then to timer to display each countdown:
retrieveDateComponants(deadlineDateChosen: deadlineDatesAll.description)
var dataComponants:Array = retrieveDateComponants(deadlineDateChosen: deadlineDatesAll.description)
var returnedDueDateString = updateTime(yearExtract: dataComponants[0], monthExtract: dataComponants[1], dayExtract: dataComponants[2], hourExtract: dataComponants[3], minExtract: dataComponants[4], secsExtract: dataComponants[5])
cell.detailTextLabel?.text = "Due In: \(returnedDueDateString)"
}
}
cell.accessoryType = item.done == true ? .checkmark : .none
}else {
cell.textLabel?.text = "No Item Found"
}
return cell
}
//UPDATE countdowns function:
@objc func updateTime(yearExtract:String, monthExtract:String, dayExtract:String,hourExtract:String,minExtract:String, secsExtract:String) -> (String) {
var deadlineTimeDueString : String = ""
let futureDate: Date = {
var future = DateComponents(
year: Int(yearExtract),
month: Int(monthExtract),
day: Int(dayExtract),
hour: Int(hourExtract),
minute: Int(minExtract),
second: Int(secsExtract) )
return Calendar.current.date(from: future)!
}()
var countdownComp: DateComponents {
return Calendar.current.dateComponents([.day, .hour, .minute, .second], from: Date(), to: futureDate)
}
let countdown = countdownComp //only compute once per call
let days = countdown.day!
let hours = countdown.hour!
let minutes = countdown.minute!
let seconds = countdown.second!
print((String(format: "OUTPUT TEST: %02d:%02d:%02d:%02d", days, hours, minutes, seconds)))
if seconds < 0 {
deadlineTimeDueString = String("OVERDUE")
} else if seconds > 0 {
deadlineTimeDueString = String(format: "%02d Days, %02d Hours, %02d Mins & %02d Secs", days, hours, minutes, seconds)
}
return deadlineTimeDueString
}
一切正常,除了倒计时时间不会刷新标签,除非我手动单击另一个单元格或同一个单元格。剩余时间有效并每秒更新一次。
任何帮助将不胜感激 谢谢MFK
【问题讨论】:
-
嗨 Rob 感谢您的回复 - 我正在使用 deadlineTimeDueString 作为全局变量。它在函数 updateTime() 中处理。对于所有设置了时间的单元格,我得到的值似乎都是正确的。我只希望字幕每秒刷新一次,从而直观地显示倒计时。 - 当您说添加日志时,我不确定我是否理解?喜欢向控制台添加打印语句?
-
我明白了。感谢那。我对 Swift 还是很陌生,但我很欣赏 Rob 的建议。您认为使用一个计时器让表格重新加载是正确的做法吗?
-
我同意秒对于 UX 来说可能有点太多了,我肯定会在更新时考虑这一点。我要做一些测试,然后从那里检查。将及时向大家发布。再次感谢您的帮助
-
嗨 Rob - 我已经设法创造了一些回报,并对我从这些函数中得到的回报感到满意。我已经编辑了我的代码,并且还在其中插入了更新功能。 -- 您在之前的 cmets 中提到您可以更新单元格的标签。我该怎么办?亲切的问候 MFK
标签: swift uitableview timer countdown