在 shouldPerformSegue 中显示 UIAlertViewController

Displaying a UIAlertViewController in shouldPerformSegue

在我的项目中,我设置了一个 UITableView,其单元格绑定到一个 segue,将用户带到另一个 ViewController,其中单元格的数据得到详细显示。但是,并非所有单元格都应执行转接(例如,单元格中显示的记录无效且不应显示,因此无需转到详细信息控制器)。

对于此任务,我使用 UIViewController 的 shouldPerformSegue 方法:(我在以下代码片段中假设 table 中的第二行是一个不应该执行 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 滚动 table 视图或再次点击等操作。

经过一些尝试和错误我找到了一个解决方案:当我将它强制到主线程时,警报 将在点击 "erroneous" 单元格后立即 显示:

DispatchQueue.main.async {
    present(alert, animated: true, completion: nil)
}

这对我来说是违反直觉的,因为 prepareForSegue 方法已经在主线程上执行了。所以我的问题是:UIAlertController 的不稳定行为从何而来,我是否需要在主线程上强制显示它,还是我做错了什么?

并不是说shouldPerformSegue不在主队列中,而是这个函数参与了segue过程,所以此时再换个角度看是个坏主意。

通过使用异步调度,您允许当前的 segue 进程在出现警报之前完成(或在这种情况下被中止)。

我认为这是解决您问题的合理方法。