iOS使用performSegue跳转视图失败,提示视图不在窗口层级
解决“Attempt to present ... whose view is not in the window hierarchy”错误
核心问题出在你调用dismissPage(nil)后立刻执行performSegue——dismiss操作是异步完成的,当你发起Segue时,当前TaxaLayoutFormViewController的视图还没完全从窗口层级中移除,此时尝试触发Segue就会抛出这个错误。
修复方案
把Segue操作放到dismiss的完成回调里,确保当前控制器完全消失后再执行跳转:
如果你的dismissPage是系统dismiss方法的简单封装,直接修改onReceiveData方法,将executeOrder的调用移到dismiss的completion闭包中:
extension TaxaLayoutFormViewController: BaseDelegate { func onReceiveData(fromClass: AnyClass, param: Int, result: Bool, object: AnyObject?) { DispatchQueue.main.async { if param == Param.Contact.TAXA_GET_CAMPO_TAXA_RESPONSE { self.dismiss(animated: true) { [weak self] in guard let self = self else { return } if result { guard let response = object as? GetTaxasResponse else { return } self.executeOrder(response: response) } } } } }
如果dismissPage是自定义方法,需要先给它添加completion回调支持:
func dismissPage(_ sender: Any?, completion: (() -> Void)? = nil) { self.dismiss(animated: true, completion: completion) }
之后调用时改为:
self.dismissPage(nil) { [weak self] in guard let self = self else { return } if result { guard let response = object as? GetTaxasResponse else { return } self.executeOrder(response: response) } }
补充说明
- 你在
viewDidLoad中调用performSegue正常,是因为此时控制器视图已经完成加载并处于窗口层级内。 - 其他控制器无此问题,大概率是它们没有在dismiss后立即触发跳转的场景,或者跳转前视图状态是稳定的。
内容的提问来源于stack exchange,提问作者Daniel Catini
相关产品推荐
相关产品推荐

