从AppDelegate发起多Segue:UNNotificationAction跳转第三层页面失败
解决通知回调中连续触发Segue跳转失败的问题
我明白你遇到的问题了——在通知回调里连续触发两个Segue时,第二个总是失败对吧?这其实是因为Segue的执行是异步的,第一个Segue还没完成(ViewController 2还没完全加载并加入导航栈),你就尝试触发第二个Segue,这时候系统找不到对应的Segue或者ViewController 2还没准备好处理Segue跳转。
下面是具体的解决思路和代码实现:
核心思路
不在通知回调里直接触发两个Segue,而是:
- 在通知回调中只触发第一个Segue(Segue A),同时传递需要跳转到详情页的标记和数据;
- 在ViewController 2加载完成并显示后,自动触发第二个Segue(Segue B)。
代码实现
1. 修改初始ViewController的通知回调和Segue准备方法
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { // 从通知内容中获取详情页需要的数据(如果有的话) let notificationUserInfo = response.notification.request.content.userInfo // 只触发第一个Segue,把数据作为sender传递 performSegue(withIdentifier: "SegueAIdentifier", sender: notificationUserInfo) completionHandler() } override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if segue.identifier == "SegueAIdentifier" { guard let vc2 = segue.destination as? ViewController2, let userInfo = sender as? [String: Any] else { return } // 给ViewController2设置标记:需要自动跳转到详情页 vc2.shouldAutoPushToDetail = true // 传递详情页需要的数据 vc2.detailPageData = userInfo["yourDetailKey"] as? YourDataModelType } }
2. 在ViewController2中添加自动触发Segue的逻辑
// 定义标记变量和数据变量 var shouldAutoPushToDetail = false var detailPageData: YourDataModelType? override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) // 检查标记,如果需要则触发Segue B if shouldAutoPushToDetail { performSegue(withIdentifier: "SegueBIdentifier", sender: detailPageData) // 重置标记,避免重复触发(比如用户返回后再次进入VC2时) shouldAutoPushToDetail = false } } // 准备Segue B的跳转数据 override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if segue.identifier == "SegueBIdentifier" { guard let detailVC = segue.destination as? DetailViewController, let data = sender as? YourDataModelType else { return } detailVC.receivedData = data } }
关键注意事项
- 一定要在
viewDidAppear中触发Segue B,而不是viewDidLoad:因为viewDidLoad时ViewController2虽然完成了加载,但还没被添加到导航控制器的栈中,这时候调用performSegue可能会失败;viewDidAppear时,VC2已经完全显示在导航栈里,Segue可以正常执行。 - 确保Storyboard中Segue A和Segue B的Identifier与代码中的完全一致,且Segue B是从ViewController2指向详情ViewController的正确类型Segue(比如
Show类型)。
内容的提问来源于stack exchange,提问作者SimonMoss
相关产品推荐
相关产品推荐

