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

切换标签页后init()调用后ViewController生命周期方法未触发

切换标签页后Push视图控制器时生命周期方法(loadView/viewDidLoad)未触发的问题

问题重现

从主标签页界面通过以下代码调用CommonListViewController:

self?.navigator.go(module: CommonListBuilder(mode: .vacation), mode: .push(animated: false))

CommonListBuilder的build()方法实现:

func build() -> BaseViewController {
    CommonListViewController(interactor: CommonListInteractor(mode: mode), mode: mode)
}

已确认build()和CommonListViewController的init方法均被执行:

init(
    interactor: CommonListInteractorProtocol,
    mode: CommonListMode
) {
    self.interactor = interactor
    self.mode = mode
    self.adapter = CommonListTableAdapter(mode: mode)
    self.searchAdapter = CommonListSearchAdapter()
    super.init()
    interactor.sendMetrics(event: .openScreen, params: mode.paramsForOpenScreen)
}

但loadView、viewDidLoad等生命周期方法均未触发,且该问题仅在切换标签页后出现,首次启动时无异常。

可能的原因及解决方案

1. 标签页导航栈被意外替换或释放

切换标签页时,若当前标签页对应的UINavigationController实例被重新初始化、释放,或其控制器栈被错误清空/替换,会导致新push的控制器无法关联到活跃导航栈,进而无法触发生命周期。

  • 排查:检查标签页切换逻辑(如UITabBarController的viewControllers赋值逻辑),确保切换后当前标签页的UINavigationController是未被替换的活跃实例。
  • 验证:push前打印self?.navigator对应的导航控制器内存地址,对比首次启动和切换标签页后的地址是否一致。

2. 自定义导航器(navigator)的push逻辑状态异常

如果自定义navigator在标签页切换后,内部维护的当前导航控制器引用失效,会导致仅创建了控制器实例,但未真正将其添加到导航栈。

  • 排查:查看navigator.go(module:mode:)的实现,确认push时是否正确获取当前活跃的UINavigationController,并执行了pushViewController(_:animated:)方法。
  • 修复示例:确保navigator始终从活跃的标签页中获取导航控制器:
func go(module: ModuleBuilder, mode: NavigationMode) {
    let vc = module.build()
    guard let tabBarVC = UIApplication.shared.keyWindow?.rootViewController as? UITabBarController,
          let currentNav = tabBarVC.selectedViewController as? UINavigationController else {
        return
    }
    switch mode {
    case .push(let animated):
        currentNav.pushViewController(vc, animated: animated)
    // 其他导航逻辑分支
    }
}

3. BaseViewController的生命周期逻辑被破坏

如果BaseViewController的init()或生命周期方法被错误重写,可能导致子类的生命周期触发逻辑失效,且仅在特定场景(如标签页切换后)暴露问题。

  • 排查:检查BaseViewController的init()、loadView方法,确保正确调用父类方法(如super.init()),且未手动将view设置为nil或干扰视图加载流程。

4. 控制器未被添加到视图层级

虽然init方法执行,但如果navigator的push逻辑存在分支错误,导致未实际执行pushViewController操作,控制器未被加入导航栈,系统不会触发其生命周期。

  • 排查:在navigator.go方法中添加日志,确认pushViewController是否被调用,以及传入的控制器实例是否正确。
  • 验证:push后打印当前导航栈的viewControllers数组,查看是否包含CommonListViewController实例。

内容的提问来源于stack exchange,提问作者MaryLitv21

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 10:45:46