在我的项目中,我设置了一个UITableView,其单元格绑定到一个segue,将用户带到另一个ViewController,其中详细显示来自单元格的数据。但是,并非所有单元格都应执行segue(例如,单元格中显示的记录无效且不应显示,因此不需要进入详图控制器。)
对于此任务,我使用UIViewController的shouldPerformSegue
方法:(我假设在下面的代码片段中,表中的第二行是不应该执行segue的那一行)
override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool {
guard let indexPath = tableView.indexPathForSelectedRow else {
return false
}
if indexPath.row == 1 {
let alert = UIAlertController(
title: "Invalid record",
message: "This record is malformed, can't display the data.",
preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Okay :(", style: .default))
present(alert, animated: true, completion: nil)
return false
} else {
return true
}
}
这会导致一些奇怪的行为:每当我点击第二行时,警报仅在敲击一两秒后显示,有时甚至在点击后五秒钟显示,有时在我执行其他UI动作之前根本不会显示警报比如滚动表格视图或再次点击。
经过一些试验和错误后,我找到了一个解决方案:当我强行将“错误”单元格强制到主线程时,立即显示警告 :
DispatchQueue.main.async {
present(alert, animated: true, completion: nil)
}
这对我来说是违反直觉的,因为prepareForSegue
方法已经在主线程上执行了。所以我的问题是:UIAlertController的不稳定行为来自何处,是否需要在主线程上强行显示或者我做错了什么?
答案 0 :(得分:1)
并不是shouldPerformSegue
不在主队列上,而是在segue过程中涉及到这个函数,所以在这一点上展示另一个视图是个坏主意。
通过使用异步调度,您可以在发出警报之前完成当前的segue进程(或在此情况下中止)。
我认为这是解决问题的合理方法。