Why does my SwiftUI app crash when navigating backwards after placing a `NavigationLink` inside of a `navigationBarItems` in a `NavigationView`?

后端 未结 9 1137
轮回少年
轮回少年 2020-12-04 12:25

EDIT: This has been fixed in iOS 13.3!

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

struct Parent: View {         


        
9条回答
  •  挽巷
    挽巷 (楼主)
    2020-12-04 12:36

    This also has frustrated me for quite some time. Over the past few months, depending on the Xcode version, simulator version and real device type and/or version, it has gone from working to failing to working again, seemingly at random. However, recently it has been failing consistently for me, so yesterday I took a deep dive into it. I am currently using Xcode Version 11.2.1 (11B500).

    It looks like the issue revolves around the Nav Bar and the way the buttons were added to it. So instead of using a NavigationLink() for the button itself, I tried using a standard Button() with an action that sets a @State var that activates a hidden NavigationLink. Here is a replacement for Robert's Parent View:

    struct Parent: View {
        @State private var showingChildView = false
        var body: some View {
            NavigationView {
                VStack {
                    Text("Hello World")
                    NavigationLink(destination: Child(),
                                   isActive: self.$showingChildView)
                    { EmptyView() }
                        .frame(width: 0, height: 0)
                        .disabled(true)
                        .hidden()            
                 }
                 .navigationBarItems(
                     trailing: Button(action:{ self.showingChildView = true }) { Text("Next") }
                 )
            }
        }
    }
    

    For me, this works very consistently across all simulators and all real devices.

    Here are my helper views:

    struct HiddenNavigationLink: View {
    
        public var destination:  Destination
        public var isActive: Binding
    
        var body: some View {
    
            NavigationLink(destination: self.destination, isActive: self.isActive)
            { EmptyView() }
                .frame(width: 0, height: 0)
                .disabled(true)
                .hidden()
        }
    }
    
    struct ActivateButton

    Here is an example of the usage:

    struct ContentView: View {
        @State private var showingAddView: Bool = false
        var body: some View {
            NavigationView {
                VStack {
                    Text("Hello, World!")
                    HiddenNavigationLink(destination: AddView(), isActive: self.$showingAddView)
                }
                .navigationBarItems(trailing:
                    HStack {
                        ActivateButton(activates: self.$showingAddView) { Image(uiImage: UIImage(systemName: "plus")!) }
                        EditButton()
                } )
            }
        }
    }
    

提交回复
热议问题