这有点好奇……
有许多 UI 控件具有“内部流程”——也就是说,发生了一些我们没有立即意识到的事情。
一个例子是标准的UIButton。在触摸/触摸序列期间,按钮的标题标签会从.normal 交叉淡入淡出到.highlighted 并再次返回。
所以,我的假设是:
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if indexPath.row == 0 {
// 1
tableView.deselectRow(at: indexPath, animated: true)
} else {
DispatchQueue.main.async {
// 2
tableView.deselectRow(at: indexPath, animated: true)
}
}
}
对于第一种情况,UIKit 可能会将高亮/取消高亮序列“排队”。
而在第二种情况下,我们告诉表格视图在下一个运行循环中取消选择该行......这将立即发生。那时,我们(实际上)中断了默认顺序,并且表格视图在它完成之前(或者实际上,在它开始之前)突出显示该行之前取消突出显示该行。
更奇怪的是...如果我们选择了一行,然后在稍后的时间点(例如在其他地方点击)并然后调用tableView.deselectRow(at: indexPath, animated: true),动画就会出现 要短得多,甚至看起来都没有动画效果。
这里有一些可以玩的东西——也许你会找到一种适合你目标的方法。
class DeselViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
let noAnimBtn = UIBarButtonItem(title: "No Anim", style: .plain, target: self, action: #selector(noAnim(_:)))
let animBtn = UIBarButtonItem(title: "With Anim", style: .plain, target: self, action: #selector(withAnim(_:)))
navigationItem.rightBarButtonItems = [animBtn, noAnimBtn]
}
@objc func noAnim(_ b: Any?) -> Void {
if let p = tableView.indexPathForSelectedRow {
tableView.deselectRow(at: p, animated: false)
}
}
@objc func withAnim(_ b: Any?) -> Void {
if let p = tableView.indexPathForSelectedRow {
UIView.animate(withDuration: 0.3, animations: {
self.tableView.deselectRow(at: p, animated: false)
})
}
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 8
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
switch indexPath.row {
case 0:
cell.textLabel?.text = "Regular deselection"
case 1:
cell.textLabel?.text = "Async deselection"
case 2:
cell.textLabel?.text = "Async deselection with Anim Duration"
case 3:
cell.textLabel?.text = "Asnyc Delay deselection"
case 4:
cell.textLabel?.text = "Asnyc Delay Plus Anim Duration deselection"
case 5:
cell.textLabel?.text = "Asnyc Long Delay deselection"
case 6:
cell.textLabel?.text = "Asnyc Long Delay Plus Anim Duration deselection"
default:
cell.textLabel?.text = "Manual deselection"
}
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
switch indexPath.row {
case 0:
tableView.deselectRow(at: indexPath, animated: true)
case 1:
DispatchQueue.main.async {
tableView.deselectRow(at: indexPath, animated: true)
}
case 2:
DispatchQueue.main.async {
UIView.animate(withDuration: 0.3, animations: {
tableView.deselectRow(at: indexPath, animated: true)
})
}
case 3:
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1, execute: {
tableView.deselectRow(at: indexPath, animated: true)
})
case 4:
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1, execute: {
UIView.animate(withDuration: 0.3, animations: {
tableView.deselectRow(at: indexPath, animated: true)
})
})
case 5:
DispatchQueue.main.asyncAfter(deadline: .now() + 0.75, execute: {
tableView.deselectRow(at: indexPath, animated: true)
})
case 6:
DispatchQueue.main.asyncAfter(deadline: .now() + 0.75, execute: {
UIView.animate(withDuration: 0.3, animations: {
tableView.deselectRow(at: indexPath, animated: true)
})
})
default:
()
// leave selected
}
}
}
将其设置为导航控制器的根视图,以便它可以放置“手动”取消选择的右栏按钮: