使用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
相关产品推荐
相关产品推荐

