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()
}
}
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:
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") })
}
}
}
Is this a SwiftUI bug or expected behavior?
EDIT: 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 :).
EDIT: 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.
EDIT: This has been fixed in iOS 13.3!
It is solved in iOS 13.3. Just update your OS and xCode.
This is a major bug and I can't see a proper way to work around it. Worked fine in iOS 13/13.1 but 13.2 crashes.
You can actually replicate it in a much simpler way (this code is literally all you need).
Hope Apple sort it out as it will surely break loads of SwiftUI apps (including mine).
Based on the information that you guys provided and specially a comment that @Robert made about where the NavigationView is placed I have found a way to workaround the issue at least on my specific scenario.
In my case I had a TabView that was enclosed in a NavigationView like this:
This code crashes as everyone is reporting in iOS 13.2 and works in iOS 13.1. After some research I figured out a workaround to this situation.
Basically, I am moving the NavigationView to each screen separately on each tab like this:
Somehow goes against the SwiftUI premise of simplicity but it works on iOS 13.2.
As a workaround, based on Chuck H's answer above, I've encapsulated the NavigationLink as a hidden element:
Then you can use it within a NavigationView (which is crucial) and trigger it from a Button in a nav bar:
Wrap this in "//HACK" comments so when Apple fixes this you can replace it.
FWIW - The solutions above suggesting a hidden NavigationLink Hack is still the best workaround in iOS 13.3b3. I have also filed a FB7386339 for posterity's sake, and was closed similarly to other aforementioned FBs: "Potential fix identified - For a future OS update".
Fingers Crossed.
Xcode 11.2.1 Swift 5
GOT IT! It took me a couple days to figure this one out...
In my case when using SwiftUI I am getting a crash only if the bottom of my list extended beyond the screen and then I try to "move" any list items. What I ended up finding out is that if I have too much "stuff" underneath the List() then it crashes on the move. For instance, below my List() I had a Text(), Spacer(), Button(), Spacer() Button(). If I commented out any ONE of those objects then suddenly I could not recreate the crash. I am not certain what the limitations are, but if you are getting this crash then try removing objects below your list to see if it helps.