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

使用reloadRootPageControllers移除返回按钮后3D Touch触发报错

解决使用reloadRootPageControllers()移除返回按钮后3D Touch触发报错的问题

我刚好碰到过一模一样的问题!你用reloadRootPageControllers()移除左上角返回按钮的思路是对的,但这个方法在页面还没完成初始化或者有过渡动画的时候调用,就会和3D Touch的弹出操作冲突,导致那个_puic_setViewControllers:animated: called on while an existing transition or presentation的错误。

问题根源

问题出在你选择的调用时机——awake(withContext:)方法里,此时界面可能还在加载过渡的过程中,直接调用重载根控制器的方法会打断系统的默认过渡流程,和3D Touch的弹出操作产生并发冲突,从而抛出错误。

解决方案

你只需要把调用reloadRootPageControllers()的时机延后,给系统足够的时间完成初始化和过渡即可,这里有两个靠谱的方案:

方案一:移到willActivate()方法中执行

willActivate()是在界面即将显示给用户时触发的,此时初始化和过渡流程基本完成,不会和3D Touch操作冲突。为了避免重复调用,我们可以加一个标记位:

private var hasReloadedRootControllers = false

override func willActivate() {
    super.willActivate()
    
    guard !hasReloadedRootControllers else { return }
    WKInterfaceController.reloadRootPageControllers(withNames: ["MainController"], contexts: [], orientation: .horizontal, pageIndex: 0)
    hasReloadedRootControllers = true
}

方案二:使用延迟执行(如果方案一仍有问题)

如果你的场景下willActivate()还是会出现冲突,可以尝试给系统留一点缓冲时间,用DispatchQueue.main.asyncAfter延迟执行:

override func awake(withContext context: Any?) {
    super.awake(withContext: context)
    
    DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
        WKInterfaceController.reloadRootPageControllers(withNames: ["MainController"], contexts: [], orientation: .horizontal, pageIndex: 0)
    }
}

这两个方案都能有效避免过渡操作的冲突,既保留了移除返回按钮的效果,又不会触发3D Touch的报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 11:27:41