WKScriptMessage回调中执行performSegue报错,同VC其他场景正常求解
问题分析与解决方案
这个问题我之前做WKWebView交互时也碰到过,核心原因主要有两个,咱们一步步拆解:
1. JS消息回调不在主线程(最常见的坑)
WKWebView的userContentController(_:didReceive:)方法是在后台线程触发的,而iOS要求所有UI操作(包括Segue跳转)必须在主线程执行。而你提到的didStartProvisionalNavigation方法是WebKit在主线程回调的,所以那里执行跳转完全正常。
解决办法很简单,把Segue调用包裹到主线程队列里就行:
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) { // 强制在主线程执行UI操作 DispatchQueue.main.async { self.performSegue(withIdentifier: "segueError2", sender: self) } }
2. 视图控制器的视图尚未加入窗口层级
如果加了主线程调用还是报错,那就要考虑:收到JS消息时,simpleBrowerVC的视图可能还没完全加载到应用窗口中(比如VC刚被push但还没完成展示,或者已经被弹出销毁了)。
可以加个安全检查,确保当前VC的视图确实在窗口层级里:
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) { DispatchQueue.main.async { // 先确认视图已加载且在窗口中 guard self.isViewLoaded, self.view.window != nil else { print("simpleBrowerVC的视图不在窗口层级,无法执行Segue") return } self.performSegue(withIdentifier: "segueError2", sender: self) } }
额外小建议
- 可以在
viewDidAppear(_:)里加个标记位,比如private var isViewReady = false,在viewDidAppear里设为true,然后接收消息时先判断这个标记,避免在视图还没显示时触发跳转。 - 如果JS消息是页面加载早期就发送的,建议调整JS逻辑,等页面完全加载完成后再给原生发消息,这样能避免时机问题。
内容的提问来源于stack exchange,提问作者Greensouth
相关产品推荐
相关产品推荐

