Currently I have the opportunity to work with SwiftUIs new NavigationStack
view which allows easy programmatic push and pop. I have to say that it works fairly well for my use cases, which impressed me. But just recently I experienced a weird behavior where a simple detail navigation from a list of entries causes two detail views being pushed onto the stack instead of one. The solution to that issue in the end was very interesting.
Setup
The reproducible setup is quite small in this case. It offers a list of some string elements, which, when tapped on, should continue to push a detail view onto the stack.
The Bug
Now it gets interesting. When we actually execute the code, we can see the flow works for "a"
and "b"
but for "c"
and "d"
there are two or even three detail views being pushed onto the stack. Maybe some of you already knew what I want to point out next.
The main part of interest here is the NavigationStack
. It needs a binding to a path
. This path represents the navigation stack. Meaning, when we push an element to that stack, the .navigationDestination
would be triggered, because we have defined to react on String
types being pushed to the stack.
Within the ForEach
loop we have indicated that the identifiable
part of our items in the list are the items themselves. Since our items in the list now contains duplicates, the navigation is actually triggered twice or three times even. Once for each element with the same identifiable value. This really caught me off guard when it was implemented in a real project. In that project it was also not that obvious that there were multiple elements with the same identifier, only when looking at the items in more detail, I could understand and reproduce that behavior.
Whats also a little bit funny, even Xcode gives us this hint, which unfortunately was covered in a lot of other debug messages in the real project...what a shame 🙈
Conclusion
What can we learn out from this example ?
- Xcode does tell us about the certain issues we have in our code, sometimes these messages are just buried in the logs
- Always make sure that when you use
NavigationStack
,NavigationLink
and.navigationDestination
withIdentifiable
objects, they are actually unique
I hope this small post gave some insights about a simple incident that might cause some frustration in a bigger project where weird things might not be that obvious in th beginning. At least for me, I learned a valuable lesson.
If you find any mistake or would like to reach out to me please do so 🙂
See you next time 👋