1

Given this View:

struct ContentView: View {

@State var link1Active: Bool = false

var body: some View {
    NavigationView {
        List {
            NavigationLink(destination: Text("Link1 Destination"), isActive: $link1Active) {
                Text("Click me 1")
            }
            NavigationLink(destination: Text("Link2 Destination")) {
                Text("Click me 2")
            }
        }
        Text("View 1")
        Text("View 2")
    }
    .onAppear {
        link1Active = true
        print("in here!")
    }
}

}

When the app starts on iPad in landscape mode, I see two columns "View 1" and "View2".

enter image description here

I would expect to see "Link 1 Destination" in the left column, but its not shown.

However when I click the toggle sidebar button the "View 1" is replaced.

enter image description here

Is this an issue with the way the views are setup in swiftui?

Jozef Dransfield
  • 524
  • 4
  • 11

1 Answers1

0

The problem is simply that the NavigationLink is not in existence when the .onAppear is called. .onAppear sets link1Active to true (I verified this by printing the value in your print() statement in .onAppear), but nothing is using it until the main List view is opened and on screen. I really don't think this is a true "fix", but the only way you are going to show the destination is simple with a conditional like:

        (!link1Active ? Text("View 1") : Text("Link1 Destination"))

Since this is a minimal reproducible example, I am not sure of your use case, but I think you need to rethink how you are showing your views.

Yrb
  • 8,103
  • 2
  • 14
  • 44
  • 1
    My use case is a 3 column layout for Mac and iOS. Similar to Apple Mail, Where Sidebar is for picking a source to fill the list view in the first column. This works fine on the Mac but on the iPad because the Sidebar isn't shown by default the user is left looking at a blank view. Would there be a better way to displays the views then? – Jozef Dransfield Sep 29 '21 at 14:36
  • That really doesn't give me enough to suggest anything definite. For the iPad, you are simply going to have to have the initial view be the view that displays the data, and not have the other view in between. I am not sure why having the blank view would ever be needed. Essentially, you are displaying one view, but you really want to display another, so when the first view appears, you have it immediately navigate to the second view that you want displayed. I don't really get why you would want that, instead, just leave out the first view, and display the second. – Yrb Sep 29 '21 at 15:39
  • @Yrb for what it’s worth, I’m experiencing the same issue as OP and can explain why I don’t want to implement what you’re suggesting. For one, it would mean writing more code to handle initialising the middle column view versus just leaving that job to the `isActive` or `tag:selection` initialisers for NavigationLink. Additionally, if you implement what you suggested, you may also notice that even though (e.g.) the middle column and the first navigation link destination views are the same, the nav link doesn’t have a selected state, and tapping the nav link causes a re-render. – Dan Eden Aug 29 '22 at 16:13