TLDR: The problem happens with just 2 navigations.
Adding a third navigation stops the issue.
In my case I had:
(1) A tab view with a root view that had 2 navigation starting points
(2) the first and second navigations have quite a lot of nested views
(3) adding .navigationViewStyle(StackNavigationViewStyle() fixed the issue only for root views that had only one starting point of navigation
(4) as soon as I had another navigation coming from the same view the problem reappeared (only for iOS 14.5 to 14.8)
(5) solely adding the
NavigationLink(destination: EmptyView()) {
EmptyView()
}
didn't work for me
(6) On my project I have a coordinator that is responsible for creating the viewModels (that are published properties) and I have a ContainerView that will handle all the navigation. The navigation links are created based on the existence or not of a viewModel, so if a viewModel exists that view will be presented and when the view is dismissed the viewModel will be set to nil. (I'll add the code that does that at the end)
(7) for some weird reason, adding a third navigation to the view that is responsible for the navigation stopped my container view to be re-rendered and the view to stop being popped back.
Simply adding the NavigationLink to the container didn't work, but using the modifier I'm using and setting the destination to be the Empty NavigationLink did.
This is the code that is used for the navigation:
func navigation<Item, Destination: View>(
item: Binding<Item?>,
@ViewBuilder destination: (Item) -> Destination
) -> some View {
let isActive = Binding(
get: { item.wrappedValue != nil },
set: { value in
if !value {
item.wrappedValue = nil
}
}
)
return navigation(isActive: isActive) {
item.wrappedValue.map(destination)
}
}
func navigation<Destination: View>(
isActive: Binding<Bool>,
@ViewBuilder destination: () -> Destination
) -> some View {
overlay(
NavigationLink(
destination: isActive.wrappedValue ? destination() : nil,
isActive: isActive,
label: { EmptyView() }
)
)
}
This is how my container view works. My coordinator has Published properties that are optional viewModels and the existence or not of that viewModel is what triggers the isActive value on the navigation link. Adding that last .navigation worked. My empty container just has the empty navigationLink