【问题标题】:SwiftUI NavigationView with List programmatic navigation does not work带有列表编程导航的 SwiftUI NavigationView 不起作用
【发布时间】:2021-06-17 14:06:09
【问题描述】:

我正在尝试在 NavigationView 中进行编程导航,但由于某种原因,我无法在视图之间切换。从父视图切换时,一切正常 - 但是当我在其中一个子视图中尝试切换时,我会得到这种奇怪的行为(屏幕来回切换)。我尝试禁用动画,但这没有帮助。奇怪的是,如果我删除一个列表和.navigationViewStyle(StackNavigationViewStyle()) 一切都会开始工作 - 但我需要一个列表。

这似乎有点类似于Deep programmatic SwiftUI NavigationView navigation,但我没有深层嵌套,它仍然不起作用。

我使用的是 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()
    }
}

这是我得到的行为:

【问题讨论】:

    标签: ios swiftui


    【解决方案1】:

    导航视图/链接旨在直接从父级操作到子级,如果您打破该顺序,则不应通过 NavLink 使用导航。

    您需要做的是使用fullScreenCover,我认为它可以很好地解决您的问题。复制并粘贴代码以了解我的意思。

    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()
            }
    
        }
    }
    

    【讨论】:

    • 这确实有助于我在 A 或 B 中打开新视图,但我希望为用户提供 NavigationView 体验。此外,虽然没有反映在我的问题中,但在我的实际用例中,我的列表仅显示在屏幕的一半上,因此 fullScreenCover 对我不起作用:(
    【解决方案2】:

    如果您只希望呈现的视图占据屏幕的一半,我建议使用 ZStack 将视图呈现在主窗口的顶部。 您可以将自己的自定义后退按钮添加到左上角(或其他位置)。 这将允许两种视图轻松呈现和切换。 您还可以添加一个 withAnimation() 以使叠加的视图很好地呈现。

    【讨论】:

      猜你喜欢
      • 2020-04-11
      • 1970-01-01
      • 1970-01-01
      • 2020-09-12
      • 2020-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-12
      相关资源
      最近更新 更多