简体   繁体   中英

SwiftUI NavigationView with List programmatic navigation does not work

I am trying to do programmatic navigation in NavigationView, but for some reason I am unable to switch between the views. When switching from the parent view everything works fine - but as soon as I am trying to switch while being in one of the child views I get this strange behaviour (screen is switching back and forth). I tried disabling animations, but this did not help. Strangely enough, if I remove a list together with .navigationViewStyle(StackNavigationViewStyle()) everything starts to work - but I need a list.

This seems to be somewhat similar to Deep programmatic SwiftUI NavigationView navigation but I do not have deep nesting and it still does not work.

I am using iOS 14.

struct TestView: View {
    @State private var selection: String? = nil

    var body: some View {
        VStack {
            NavigationView {
                VStack {
                    List {
                        NavigationLink(destination: Text("View A"), tag: "A", selection: self.$selection) { Text("A") }
                        NavigationLink(destination: Text("View B"), tag: "B", selection: self.$selection) { Text("B") }
                    }
                }
                .navigationTitle("Navigation")
            }
            .navigationViewStyle(StackNavigationViewStyle())
            Button("Tap to show A") {
                selection = "A"
            }.padding()
            Button("Tap to show B") {
                selection = "B"
            }.padding()
        }
    }
}

struct TestView_Previews: PreviewProvider {
    static var previews: some View {
        TestView()
    }
}

Here is the behaviour i get:

导航视图行为

Navigation View/Link is meant to operate from parent to child directly, if you break that order then you should not use navigate via NavLink.

What you need to do is use a fullScreenCover which I think solves your problem nicely. Copy and paste the code to see what I mean.

import SwiftUI

struct TestNavView: View {
    @State private var selection: String? = nil
    @State private var isShowing = false
    @Environment(\.presentationMode) var pMode

    var body: some View {
        VStack {
            NavigationView {
                VStack {
                    List {
                        NavigationLink(destination: Text("View A"), tag: "A", selection: self.$selection) { Text("A") }
                        NavigationLink(destination: Text("View B"), tag: "B", selection: self.$selection) { Text("B") }
                    }.fullScreenCover(isPresented: $isShowing, content: {
                        CView()
                    })
                    
                }
                .navigationTitle("Navigation")
            }
            .navigationViewStyle(StackNavigationViewStyle())
            Button("Tap to show A") {
                selection = "A"
            }.padding()
            Button("Tap to show B") {
                isShowing = true
                selection = "B"
            }.padding()
            Button("Tap to show C") {
                isShowing = true
            }.padding()
        }
    }
}

struct TestView_Previews: PreviewProvider {
    static var previews: some View {
        TestNavView()
    }
}

struct CView: View {
    @Environment(\.presentationMode) var pMode
    var body: some View {
        VStack {
            Button("Back") {self.pMode.wrappedValue.dismiss() }
            Spacer()
        Text("C")
            Spacer()
        }

    }
}

If you are only wanting the presented view to take up half the screen, I would recommend using a ZStack to present the view over top of the main window. You can add your own custom back button to the top left corner (or elsewhere). This would allow both views to presented and switched between easily. You can also add a withAnimation() to have the overlayed views to present nicely.

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