Kevin Renskers
Kevin Renskers

Reputation: 5892

NavigationLink inside a VStack is broken on iPad

Consider this very simple view: just a few links to other pages. If you run this on iPhone, everything works as expected. However, run this on the iPad in landscape, and you will notice that most of the time the links simply don't work. Broken in the sim and real device, which is surprising.

When you change the VStack to a List, everything works fine all of a sudden.

struct ContentView: View {
  var body: some View {
    NavigationView {
      VStack {
        NavigationLink(destination: Text("Link 1")) {
          Text("Link 1")
            .padding(.vertical)
        }

        NavigationLink(destination: Text("Link 2")) {
          Text("Link 2")
            .padding(.vertical)
        }

        NavigationLink(destination: Text("Link 3")) {
          Text("Link 3")
            .padding(.vertical)
        }

        NavigationLink(destination: Text("Link 4")) {
          Text("Link 4")
            .padding(.vertical)
        }
        NavigationLink(destination: Text("Link 5")) {
          Text("Link 5")
            .padding(.vertical)
        }
      }

      Text("Hello iPad")
    }
  }
}

Has anyone else run into this problem? Why does it happen, and what is the workaround? Other than the obvious "use a List" :p I am using a grid of VStacks and HStacks to show links in multiple columns, configurable per device size. So changing to a List would not be preferable if not 100% necessary.

Upvotes: 0

Views: 871

Answers (2)

user3441734
user3441734

Reputation: 17534

I suggest you to read the documentation, before you try to find some "workaround"

 // Creates an instance that presents `destination` when `selection` is set
 // to `tag`.
    public init<V>(destination: Destination, tag: V, selection: Binding<V?>, @ViewBuilder label: () -> Label) where V : Hashable

example usage

struct ContentView: View {
    @State var selection: Int? = 0
    var body: some View {
        NavigationView {
            VStack {
                NavigationLink(destination: Text("Link 0"), tag: 0, selection: $selection) {
                    Text("link 0")
                }
                NavigationLink(destination: Text("Link 1"), tag: 1, selection: $selection) {
                    Text("link 1")
                }
                NavigationLink(destination: Text("Link 2"), tag: 2, selection: $selection) {
                    Text("link 2")
                }

            }

            Text("Hello iPad user, swipe from left to continue ...")
        }
    }
}

Upvotes: 1

Kevin Renskers
Kevin Renskers

Reputation: 5892

Found a workaround:

struct ContentView: View {
  @State var showLink1 = false
  // .. and the other 4

  var body: some View {
    NavigationView {
      ZStack {
        List {
          NavigationLink(destination: Text("Link 1"), isActive: $showLink1) {
            EmptyView()
          }
          // .. and the other 4
        }
        .opacity(0)

        VStack {
          Button(action: { self.showLink1 = true  }) {
            Text("Link 1")
              .padding(.vertical)
          }
          // .. and the other 4
        }
      }

      Text("Hello iPad")
    }
  }
}

Oh, SwiftUI...

Upvotes: 0

Related Questions