You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.23 20:45:01