Swift如何在AppDelegate的applicationWillEnterForeground中调用ViewController方法
问题解答
结论
完全可以在AppDelegate的applicationWillEnterForeground方法中调用ViewController的自定义函数,你当前获取vc为nil是代码存在两处可修复的问题。
问题排查与修复方案
- 第一处:代理方法名拼写错误
你当前写的方法名是applicatioWillEnterForeground,漏了字母n,正确的系统代理方法名是applicationWillEnterForeground,拼写错误会导致系统根本不会触发这个方法执行,也会影响window属性的取值时机。
修正后的方法声明为:
func applicationWillEnterForeground(_ application: UIApplication) { if let vc = window?.rootViewController as? ViewController { vc.resetValues() } }
- 第二处:未主动设置根视图控制器
你在didFinishLaunchingWithOptions方法中没有给window赋值,也没有设置rootViewController,所以window?.rootViewController自然为nil。
如果是纯代码开发,需要在didFinishLaunchingWithOptions中添加初始化逻辑:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { window = UIWindow(frame: UIScreen.main.bounds) window?.rootViewController = ViewController() window?.makeKeyAndVisible() return true }
如果是iOS13及以上使用SceneDelegate的项目,AppDelegate不再默认管理window,生命周期逻辑迁移到了SceneDelegate中,你可以选择两种方案适配:
- 直接在SceneDelegate的
sceneWillEnterForeground方法中获取当前场景的rootViewController调用 - 如需在AppDelegate中调用,可通过活跃场景获取window:
func applicationWillEnterForeground(_ application: UIApplication) { guard let scene = UIApplication.shared.connectedScenes.first as? UIWindowScene, let vc = scene.windows.first?.rootViewController as? ViewController else { return } vc.resetValues() }
扩展注意事项
如果你的根控制器是UINavigationController、UITabBarController这类容器控制器,需要多一层类型转换才能拿到目标ViewController,以导航控制器为例:
if let nav = window?.rootViewController as? UINavigationController, let targetVC = nav.topViewController as? ViewController { targetVC.resetValues() }
内容的提问来源于stack exchange,提问作者DumbBlonde
相关产品推荐
相关产品推荐

