在将"NavigationLink"放入"NavigationView"中的"navigationBarItems"内部后,为什么向后导航时我的SwiftUI应用会崩溃? [英] Why does my SwiftUI app crash when navigating backwards after placing a `NavigationLink` inside of a `navigationBarItems` in a `NavigationView`?

查看:316
本文介绍了在将"NavigationLink"放入"NavigationView"中的"navigationBarItems"内部后,为什么向后导航时我的SwiftUI应用会崩溃?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最小的可复制示例(Xcode 11.2 beta,在Xcode 11.1中有效):

Minimal reproducible example (Xcode 11.2 beta, this works in Xcode 11.1):

struct Parent: View {
    var body: some View {
        NavigationView {
            Text("Hello World")
                .navigationBarItems(
                    trailing: NavigationLink(destination: Child(), label: { Text("Next") })
                )
        }
    }
}

struct Child: View {
    @Environment(\.presentationMode) var presentation
    var body: some View {
        Text("Hello, World!")
            .navigationBarItems(
                leading: Button(
                    action: {
                        self.presentation.wrappedValue.dismiss()
                    },
                    label: { Text("Back") }
                )
            )
    }
}

struct ContentView: View {
    var body: some View {
        Parent()
    }
}

问题似乎在于将我的NavigationLink放在嵌套在SwiftUI视图(其根视图是NavigationView)内部的navigationBarItems修饰符内.崩溃报告表明,当我向前导航至Child然后返回至Parent时,我试图弹出一个不存在的视图控制器.

The issue seems to lie in placing my NavigationLink inside of a navigationBarItems modifier that's nested inside of a SwiftUI view whose root view is a NavigationView. The crash report indicates that I'm trying to pop to a view controller that doesn't exist when I navigate forward to Child and then back to Parent.

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Tried to pop to a view controller that doesn't exist.'
*** First throw call stack:

如果我将NavigationLink放置在如下所示的视图主体中,则效果很好.

If I were to instead place that NavigationLink in the body of the view like the below, it works just fine.

struct Parent: View {
    var body: some View {
        NavigationView {
            NavigationLink(destination: Child(), label: { Text("Next") })
        }
    }
}

这是SwiftUI错误还是预期的行为?

Is this a SwiftUI bug or expected behavior?

我已经在Apple的反馈助理中打开了一个ID为FB7423964的问题,以防苹果中的任何人关心:).

I've opened an issue with Apple in their feedback assistant with the ID FB7423964 in case anyone out there from Apple cares to weigh in :).

我在反馈助手中打开的票证表明有10多个类似的已报告问题.他们已使用Resolution: Potential fix identified - For a future OS update更新了分辨率.手指交叉,很快就可以修复.

My open ticket in the feedback assistant indicates there are 10+ similar reported issues. They've updated the resolution with Resolution: Potential fix identified - For a future OS update. Fingers crossed that the fix lands soon.

此问题已在iOS 13.3中修复!

This has been fixed in iOS 13.3!

推荐答案

这对我来说是很痛苦的一点!我把它留了下来,直到我的大多数应用程序完成为止,并且我有足够的空间来处理崩溃问题.

This was quite a pain point for me! I left it until most of my app was completed and I had the mind space to deal with the crashing.

我想我们都可以同意SwifUI有一些很棒的东西,但是调试可能很困难.

I think we can all agree that there's some pretty awesome stuff with SwifUI but that the debugging can be difficult.

我认为这是一个错误.这是我的基本原理:

In my opinion, I would say that this is a BUG. Here is my rationale:

  • 如果以大约半秒的异步延迟包装presentationMode dismiss调用,则应该发现该程序将不再崩溃.

  • If you wrap the presentationMode dismiss call in an asynchronous delay of about a half-second, you should find that the program will no longer crash.

DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
    self.presentationMode.wrappedValue.dismiss()
} 

  • 这向我暗示,该错误是SwiftUI如何与所有其他UIKit代码进行接口以管理各种视图的一个意想不到的行为.根据您的实际代码,您可能会发现,如果视图中存在一些次要复杂性,则崩溃实际上不会发生.例如,如果您从一个视图中退出到一个具有列表的视图,并且该列表为空,则将在没有异步延迟的情况下崩溃.另一方面,如果在该列表视图中甚至只有一个条目,则强制循环迭代以生成父视图,您将看到崩溃不会发生.

  • This suggests to me that the bug is an unexpected behaviour way down deep in how SwiftUI interfaces with all the other UIKit code to manage the various views. Depending on your actual code, you might find that if there is some minor complexity in the view, the crash actually will not happen. For example, if you are dismissing from a view to one that has a list, and that list is empty, you will get a crash without the asynchronous delay. On the other hand, if you have even just one entry in that list view, forcing a loop iteration to generate the parent view, you'll see that the crash will not occur.

    我不确定在延迟中包装dismiss调用的解决方案是否强大.我必须测试更多.如果您对此有任何想法,请告诉我!很高兴向您学习!

    I'm not so sure how robust my solution of wrapping the dismiss call in a delay is. I have to test it much more. If you have ideas on this, please let me know! I'd be very happy to learn from you!

    这篇关于在将"NavigationLink"放入"NavigationView"中的"navigationBarItems"内部后,为什么向后导航时我的SwiftUI应用会崩溃?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    相关文章
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆