使用TableView的代理方法“didSelectRowAt”弹出警告框控件UIAlertController时,弹窗会出现1秒至5秒不等的延时。起初怀疑是模拟器卡顿的bug,但是在真机测试下仍然出现延时的情况。搜索后才得知,如此延时会在以下两个条件均满足的情况下发生:
1、TableViewCell的selectionStyle属性设置成了 .none
2、didSelectRowAt所调用的方法弹出的Controller为UIAlertController
由此我们就有了两种解决方法:
方法一:将TableViewCell的selectionStyle属性设置成 .default,但是在点击cell时cell上会有一层阴影效果。
方法二:将UIAlertController的定义与present方法强制移到主线程运行,示例代码如下:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
DispatchQueue.main.async { //在主线程运行避免cell.selectionStyle = .none时弹出延时
let alertView = UIAlertController(title: "Really wanna logout?", message: nil, preferredStyle: .alert)
let action1 = UIAlertAction(title: "OK", style: .destructive, handler: nil)
let action2 = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
alertView.addAction(action1)
alertView.addAction(action2)
self.present(alertView, animated: true, completion: nil)
}
}
重新编译运行,可以发现弹窗延时的问题已经解决。原因可能是UIKit内部存在线程调用的Bug,这里就不做详细的分析了。