6
votes

I'm trying to do a simple SwiftUI navigation from one view to another and back using a bar button item. I have tried three different approaches to calling a new view. Using a Button in the body view works, but using NavigationBarItems in the navigation bar fails in two different ways.

Here's the start view:

struct ContentView: View {
    @State private var showSecondView = false
    var body: some View {
        NavigationView {
            VStack {
                Text("This is the content view")
                    .navigationBarTitle("Nav Title")
//this works ONCE only:
                    .navigationBarItems(trailing: Button(action: {self.showSecondView.toggle()}) {
                        Text("SecondView")
                    })
//this always fails on return to contentview with error:
//Tried to pop to a view controller that doesn't exist
//                .navigationBarItems(trailing:
//                    NavigationLink(destination: SecondView()) {
//                        Text("SecondNav")
//                    }
//                )
//This always works:
                Button(action: {self.showSecondView.toggle()} ) {
                    Text("Call Modal Second View")
                }.padding()
                Text(self.showSecondView ? "true" : "false")
            }.sheet(isPresented: $showSecondView) {
                SecondView()
            }
        }
    }
}

If I use a NavigationLink in the NavigationBarItems, the SecondView is displayed, but on return to the ContentView, it crashes with the error: "Tried to pop to a view controller that doesn't exist"

If I use a Button in the NavigationBarItems, the transition to the SecondView works once and only once. The return to ContentView works but the button no longer functions. Interestingly, If the first action taken is with the Button in the Body, the NavigationBarItem does not work even once.

And the simple SecondView:

struct SecondView: View {
    @Environment(\.presentationMode) var presentation
    var body: some View {
        NavigationView {
            VStack{
                Text("This is the second view")
                Button(action: { self.presentation.wrappedValue.dismiss()}) {
                    Text("Dismiss Modal")
                }.padding()
            }
        }
    }
}

I'm confused. Any guidance would be appreciated. Xcode 11.2 (11B44), Catalina 10.15

2
Working fine on my end and I'm running the same version of Xcode. I can open and dismiss the SecondView over and over again from either the Call Modal Second View button or the top-right SecondView button without any issues. Also uncommenting the code and using the trailing NavigationLink(..) works fine as well.fulvio
Hmmm. That's really confusing. I'll try to clean and restart Xcode. Thanks.JohnSF
I'm running iOS 13.1.2 if that means anything.fulvio
I cleaned, restarted Xcode and the simulator and the behavior is the same - BUT it does work with a real device. That device is 13.1.3. So I guess this is just a simulator bug. Just to make it more strange, even in the simulator, if I swipe down to dismiss the SecondView (instead of using the Dismiss Button) then the Nav Button also works every time. Guess I'm stuck using a device full time for now.JohnSF
I have noticed some weird quirks like this where Simulator vs Device behave a little differently. I recommend raising these kinds of issues when you come across them through Bug Reporting - developer.apple.com/bug-reportingfulvio

2 Answers

4
votes

This is still an issue for me, I am having the same issue with popover (Modal) presentation and pushing Second controller via NavigationLink in navigationBarItems.

This is a really serious bug. The only way it works correctly is when the NavigationLink is inside NavigationView content and not navigationBarItems.

This is a really breaking as NavigationBar buttons are suppose to work that way.

1
votes

I came across this issue today when I updated my Xcode to 11.2. According to this post it seems to be a bug with 13.2. I tested it on my actual iPhone X, which is still running 13.1.2, and it works just fine there.