2

I want to push a view programmatically instead of relying on the interface that NavigationLink provides (e.g. I want to use a button with no chevron). The correct way is to use NavigationLink with tag and selection, and an EmptyView.

When I attempt to use the following code to push a view, it works to push the view the first time:

struct PushExample: View {
  @State private var pushedView: Int? = nil

  var body: some View {
    NavigationView {
      VStack {
        Form {
          Button(action: { self.pushedView = 1 }) { Text("Push view") }
        }

        NavigationLink(destination: Text("Detail view"), tag: 1, selection: $pushedView) { EmptyView() }
      }
    }
  }
}

However, if I tap the back button on the view, and try hitting the button again, it no longer pushes the view. This is because the value pushedView is being set to 1 again, but it is already at 1. Nothing is resetting it back to nil upon pop of the Detail view.

How do I get subsequent taps of the button to push the view again?

Senseful
  • 86,719
  • 67
  • 308
  • 465
  • Works as expected (after tap Back the `pushedView == nil`). Tested with Xcode 11.2 / iOS 13.2. Do you use Xcode 11.3? – Asperi Dec 13 '19 at 20:07
  • Does this answer your question? [SwiftUI: NavigationLink not working if not in a List](https://stackoverflow.com/questions/56898702/swiftui-navigationlink-not-working-if-not-in-a-list) – Benjamin Kindle Jan 05 '20 at 14:24

1 Answers1

2

TL;DR: There is no need to reset the state variable, as SwiftUI will automatically handle it for you. If it's not, it may be a bug with the simulator.


This was a simulator bug on Xcode 11.3!

The way to check if it's a simulator bug is to run an even simpler example:

struct ContentView: View {
  var body: some View {
    NavigationView {
      NavigationLink("Push", destination: Text("Detail"))
    }
  }
}

On the Xcode 11.3 iPhone 11 Pro Max, this would only work the first time you tap the link.

This worked fine on both a 13.2 and a 13.3 device.

Therefore, when running into odd SwiftUI issues, test on device rather than the simulator.


Update: Restarting the computer didn't fix it either. Thus while SwiftUI is still new, may be better off to use a real device for testing rather than the simulator.

Senseful
  • 86,719
  • 67
  • 308
  • 465
  • Amazing! It is indeed a simulator bug (still on, Xcode 11.3.1) and works fine on device. I have a `List` with multiple selectable rows: selecting a row pushes a UIKit-bridged view, then going back and tapping the same row has no effect – the pushed view is not released at the point the back button is tapped. Going back and selecting another row in the table does push the new one but immediately pops back (because that is when the previously pushed view is released). Glad it's only on simulator, was already trying various workarounds. – stakri Jan 16 '20 at 22:55