UIApplication子类中定时器到期后如何展示指定ViewController?
解决UIApplication子类中展示ViewController的问题
嘿,我刚好处理过类似的场景,给你几个实用的方案,帮你在UIApplication子类里顺利展示目标ViewController:
方案一:获取当前活跃窗口并设置为根控制器
因为UIApplication子类本身就是UIApplication的实例,你可以通过它来获取当前的活跃窗口(适配iOS 13+的多场景模式),然后直接设置根控制器:
首先写一个获取当前窗口的工具方法:
extension UIApplication { func currentActiveWindow() -> UIWindow? { if #available(iOS 13.0, *) { return connectedScenes .filter { $0.activationState == .foregroundActive } .compactMap { $0 as? UIWindowScene } .first?.windows .filter { $0.isKeyWindow } .first } else { return keyWindow } } }
然后在你的UIApplication子类里,实例化完vc后这么用:
let storyboard = UIStoryboard(name: "Main", bundle: nil) let vc = storyboard.instantiateViewController(withIdentifier: "StartVC") if let window = self.currentActiveWindow() { // 直接替换根控制器 window.rootViewController = vc window.makeKeyAndVisible() }
方案二:获取顶层视图控制器进行Present/Push
如果不想直接替换根控制器,而是想以present或者push的方式展示新页面,可以先找到当前的顶层视图控制器:
先添加获取顶层VC的方法:
extension UIApplication { func topViewController() -> UIViewController? { guard let window = currentActiveWindow(), let rootVC = window.rootViewController else { return nil } var topVC = rootVC while let presentedVC = topVC.presentedViewController { topVC = presentedVC } return topVC } }
然后根据你的需求选择展示方式:
方式1:Present新ViewController
if let topVC = self.topViewController() { topVC.present(vc, animated: true, completion: nil) }
方式2:Push到导航栈(如果顶层是导航控制器)
if let navVC = self.topViewController() as? UINavigationController { navVC.pushViewController(vc, animated: true) }
小提示
- 因为你是在UIApplication子类中,直接用
self就可以调用上面的扩展方法,不需要再写UIApplication.shared - 如果你的定时器是在后台运行,要注意iOS的后台限制,确保定时器能正常触发哦
内容的提问来源于stack exchange,提问作者Marmelador
相关产品推荐
相关产品推荐

