Swift获取topMostViewController时如何避免返回UIAlertController
Swift 排除UIAlertController的顶层控制器获取方案
调整思路
- 原有方法递归遍历弹出控制器时未过滤UIAlertController,导致弹窗出现时返回值不符合业务预期
- 调整逻辑分为两处:
- 遍历presentedViewController时跳过UIAlertController类型实例,不进入对应递归
- 兜底判断当前返回实例如果是UIAlertController,返回它的presentingViewController
修改后的完整代码
func topMostViewController() -> UIViewController { // 仅遍历非UIAlertController类型的弹出控制器 if let presented = self.presentedViewController, !presented.isKind(of: UIAlertController.self) { return presented.topMostViewController() } if let navigation = self as? UINavigationController { return navigation.visibleViewController?.topMostViewController() ?? navigation } if let tab = self as? UITabBarController { return tab.selectedViewController?.topMostViewController() ?? tab } // 兜底处理:当前实例为UIAlertController时返回它的父弹出控制器 if self.isKind(of: UIAlertController.self) { return self.presentingViewController ?? self } return self }
调用方式
和原有调用逻辑完全一致,无需额外修改:
AppDelegate.shared.window?.rootViewController?.topMostViewController()
补充说明
如果需要同时排除其他系统弹窗类控制器(如UIActivityViewController、UIDocumentPickerViewController等),只需在类型判断条件中新增对应类型的判断即可。
内容的提问来源于stack exchange,提问作者famfamfam
相关产品推荐
相关产品推荐

