我想创建tableView并在点击单元格后更改单元格中的文本并在一个函数内执行。在Swift的第一个版本中,它起作用了,现在只是在完成后改变了
覆盖func tableView(_ tableView:UITableView,didSelectRowAt indexPath:IndexPath)
这是一个代码示例:
import UIKit
class TableViewController: UITableViewController {
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 10
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell")
cell?.textLabel?.text = "cell \(indexPath.row + 1)"
return cell!
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath)
cell?.textLabel?.text = "hello"
sleep(2)
cell?.textLabel?.text = "bye"
sleep(2)
}
}
我希望它能像这样工作: 点按小区 - >单元格文本更改为“hello”,等待2秒,然后更改为“bye”,等待另外2秒并继续
但现在它的工作原理如下: 点按小区 - >等待4秒,改为“再见”并继续
答案 0 :(得分:1)
您可以使用DispatchQueue
来获得更好的结果:
cell?.textLabel?.text = "hello"
tableView.isUserInteractionEnabled = false
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
// your code here
cell?.textLabel?.text = "bye"
tableView.isUserInteractionEnabled = true
}
答案 1 :(得分:1)
这实际上是一项比看起来更复杂的任务。
首先,永远不要在主队列上睡觉。这会锁定主线程并使您的应用显示无响应。
您需要有一个数据模型来跟踪每一行的标题,在这种情况下,还需要一个知道何时更新行的计时器。
您还需要处理用户点击一行,然后在屏幕上向后滚动该行。
允许用户点击多行并根据需要进行每次更新也会有所帮助。并且您需要在行更新之间的延迟期间处理离开表视图的用户。
这是一个支持所有这些问题的解决方案。
class TableViewController: UITableViewController {
struct RowData {
var title: String
var timer: Timer?
init(_ title: String) {
self.title = title
}
}
var rowData = [RowData]()
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return rowData.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") ?? UITableViewCell(style: .default, reuseIdentifier: "cell")
let data = rowData[indexPath.row]
cell.textLabel?.text = data.title
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
var data = rowData[indexPath.row]
if data.timer == nil {
// No timer for this row - set to "hello" and start a timer
let timer = Timer(timeInterval: 2, target: self, selector: #selector(timerTick), userInfo: indexPath, repeats: false)
RunLoop.main.add(timer, forMode: .commonModes) // Allow timer to work while scrolling
data.title = "hello"
data.timer = timer
rowData[indexPath.row] = data
tableView.reloadRows(at: [ indexPath ], with: .fade)
}
}
@objc func timerTick(_ timer: Timer) {
// Update the row to "bye" and reset the timer
let indexPath = timer.userInfo as! IndexPath
var data = rowData[indexPath.row]
data.timer = nil
data.title = "bye"
rowData[indexPath.row] = data
tableView.reloadRows(at: [ indexPath ], with: .fade)
}
override func viewDidLoad() {
super.viewDidLoad()
// Load test data
for i in 1...50 {
rowData.append(RowData("Row \(i)"))
}
}
override func viewWillDisappear(_ animated: Bool) {
if isMovingFromParentViewController || isBeingDismissed {
// Cancel all timers
for data in rowData {
if let timer = data.timer {
timer.invalidate()
}
}
}
}
}
通过一些更改,您还可以支持用户在达到“bye”值之前点击一行并将行重置为原始值。这是一个练习。