简体   繁体   中英

How to trigger a NavigationLink programmatically on appear

I am trying to trigger a NavigationLink programmatically on appear but in all cases the destination view pops immediately after appearing (iOS 13.3.1, Xcode 11.3.1) .

The setup is as follows: ContentView has a NavigationLink to DetailView1 which in turn has a NavigationLink to DetailView2. I would like the NavigationLink in DetailView1 to be triggered automatically when the DetailView1 first loads (in my actual code this would be based on a condition, but this is irrelevant here).

This is the basic code (without automatic behaviour):

import SwiftUI

struct ContentView: View {
    var body: some View {
        NavigationView {
            NavigationLink(destination: DetailView1()) {
                Text("Open Detail View 1")
            }
                .navigationBarTitle(Text("ContentView"))
        }
    }
}

struct DetailView1: View {
@State private var isActive = false

    var body: some View {
        VStack {
            NavigationLink(destination: DetailView2(), isActive: $isActive) {
                EmptyView()
            }
            Button ("Open Detail View 2") {
                self.isActive = true
            }
        }
        .navigationBarTitle(Text("Detail View 1"), displayMode: .inline)
    }
}

struct DetailView2: View {
    var body: some View {
        Text("This is Detail View 2")
            .navigationBarTitle(Text("Detail View 2"), displayMode: .inline)
    } 
}

My first approach was to set isActive to true at its declaration in DetailView1:

@State private var isActive = true

As expected, the NavigationLink is triggered, but DetailView2 is popped immediately after appearing.

I also (alternatively) tried to set isActive to true in within .onAppear

.navigationBarTitle(Text("Detail View 1"), displayMode: .inline)
.onAppear(){
    self.isActive = true
}

The result however is the same.

What actually worked was delaying setting isActive to true by at least 0.75 seconds, which in my opinion is not an acceptable workaround.

.navigationBarTitle(Text("Detail View 1"), displayMode: .inline)
.onAppear(){
    DispatchQueue.main.asyncAfter(deadline: .now() + 0.75) {
        self.isActive = true
    }
}

Is this a bug or is there a way to achieve the desired effect?

With Xcode 11.4 / iOS 13.4 works properly using .toggle() , like below

.navigationBarTitle(Text("Detail View 1"), displayMode: .inline)
.onAppear {
    self.isActive.toggle()
}

演示

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM