SwiftUI NavigationLink pops out by itself

I have a simple use case where a screen pushes another screen using the NavigationLink. There is a strange behaviour iOS 14.5 beta where the pushed screen is popped just after being pushed.

I manage to create a sample app where I reproduce it. I believe the cause is the presence of @Environment(\.presentationMode) that seem to re-create the view and it causes the pushed view to be popped.


The exact same code works fine in Xcode 12 / iOS 14.4



Here is a sample code.

Code Block swift
import SwiftUI
public struct FirstScreen: View {
  public init() {}
  public var body: some View {
    NavigationView {
      List {
        row
        row
        row
      }
    }
  }
  private var row: some View {
    NavigationLink(destination: SecondScreen()) {
      Text("Row")
    }
  }
}
struct SecondScreen: View {
  @Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
  public var body: some View {
    VStack(spacing: 10) {
      NavigationLink(destination: thirdScreenA) {
        Text("Link to Third Screen A")
      }
      NavigationLink(destination: thirdScreenB) {
        Text("Link to Third Screen B")
      }
      Button("Go back", action: { presentationMode.wrappedValue.dismiss() })
    }
  }
  var thirdScreenA: some View {
    Text("thirdScreenA")
  }
  var thirdScreenB: some View {
    Text("thirdScreenB")
  }
}
struct FirstScreen_Previews: PreviewProvider {
  static var previews: some View {
    FirstScreen()
  }
}






Post not yet marked as solved Up vote post of JanC Down vote post of JanC
51k views
  • The WA works. But this is still present in 14.7.

Add a Comment

Replies

I have this same problem. Has anyone found a solution for this bug? A public release of iOS 14.5 is nearing, and I'm looking to get it figured out beforehand.

I did see in the release notes of 14.5 beta 2 the following: "Using Published in a subclass of a type conforming to ObservableObject now correctly publishes changes. (71816443)". (Not sure if this is the cause).

This was also in the release notes of iOS 14.5 beta 2 which could more likely be the cause of the bug:
"The destination of NavigationLink that only differs by local state now resets that state when switching between links as expected. (72117345)"
I haven’t find a solution nor a workaround and this behavior is quite bad. I will file a radar.
please let me know if you find something
Post not yet marked as solved Up vote reply of JanC Down vote reply of JanC
Same problem here. iOS 14.5 messed up the whole app navigation und now views are immediately popped upon being pushed so the App jumps around and is unusable. I fear this behavior will find its way into the release version as it is also present in the latest release candidate.

Update: Found a fix which is really weird but seems to work until the real cause is found:

In the pushing view that contains the NavigationLinks, add the following meaningless Navigationlink next to your existing ones. So far it seems the problem only occurs if you have more than one NavigationLink in a view and I am sure its related to the mentioned new behavior of 14.5

Add this to your view containing your existing NavigationLinks:

Code Block swift
NavigationLink(destination: EmptyView()) {
    EmptyView()
}



  • It worked. For goodness' sake, what nonsense. Could this bug be any more senseless? I love Apple, Xcode, SwiftUI, but this is pretty nuts. It was too close to lottery odds that I found this thread. Thanks for sharing.

  • Thanks!!!!! How did you figure it out?

  • Thanks a lot!!! You saved me from a horrible bug.

yes, this seems to be a (super strange) workaround. There is a discussion about this on the Swift forums here


cheers
Post not yet marked as solved Up vote reply of JanC Down vote reply of JanC
I can confirm that this issue is still present in the release version of iOS 14.5.
Workaround is also working here.
Thank you so much, the empty navigation link works for me as well. The behaviour is still present in the current iOS 14.6 beta.
We updated our whole app and placed the empty NavigationLink in every view which already had a NavigationLink and it solved the problem for us :) Sad thing is that with the 14.5 being released, we will have to keep that thing in place for ages now even if 14.6 may solve it :/
Same problem here, fixed it with the empty NavigationLink hack, but I hope this will be fixed soon...
We've also faced this issue. Trying to get attention from Apple Engineers
Having the same issue, thanks for the workaround! Have filed a bug report, make sure you all file one too. You can reference case #FB9095424 and hopefully we can drum up some noise so the Apple Engineers notice! 🤞
Damn, thank you so much for that workaround!
I was going bananas over here after multiple users reported that bug to me today.
THANK YOU!
Thank you so much. I wasted hours on this as well.
Any updates? I've seen several threads on this and I can't figure out is it's a SwiftUI bug or not setting some state variable properly.
Spent several hours on this issue thinking I was triggering the pop myself. The workaround worked for me - thank you.
Add a Comment
Where exactly are you putting the empty navigation link? I've tried putting inside my List, inside my ForEach, before and after the list, before and after the For Each, and it only seems to fix my first link. All the others keep popping when I tap on a button in the detail view.

The button I'm pressing in the detail view makes changes to core data. Could it be a different issue? Could it be that making changes to the model, which the master view uses as well, causes the pop?
  • coopersita, I added the empty navigation link directly in front of the operative navigation link in a VStack. Sorry but I havent tried inside Lists or ForEach loops.

  • @cooperista did you manage find a solution? The problem I am experiencing sounds very similar to yours, i.e. a button that changes the model is causing the view to pop back in the navigation hierarchy.

Add a Comment