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

从AppDelegate发起多Segue:UNNotificationAction跳转第三层页面失败

解决通知回调中连续触发Segue跳转失败的问题

我明白你遇到的问题了——在通知回调里连续触发两个Segue时,第二个总是失败对吧?这其实是因为Segue的执行是异步的,第一个Segue还没完成(ViewController 2还没完全加载并加入导航栈),你就尝试触发第二个Segue,这时候系统找不到对应的Segue或者ViewController 2还没准备好处理Segue跳转。

下面是具体的解决思路和代码实现:

核心思路

不在通知回调里直接触发两个Segue,而是:

  1. 在通知回调中只触发第一个Segue(Segue A),同时传递需要跳转到详情页的标记和数据;
  2. 在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:35:06