如何放松到 SwiftUI 中的 MainView

2024-01-12

我找不到从 ViewB 转到 ContentView 而不显示第二个的方法NavigationView在另一个之上NavigationView.

struct ContentView: View {
    var body: some View {
        NavigationView{
            VStack {
                Text("Go to ViewA")
                NavigationLink(destination: ViewA()) {Text("Go")}
            }.navigationBarTitle("ContentView")
        }
    }
}

struct ViewA: View {
   @Environment(\.presentationMode) var presentationMode
    var body: some View {
        VStack {
            Text("Go to ViewB")
            NavigationLink(destination: ViewB()) {Text("Go to B")}
            Text("Go back")
            Button(action: { self.presentationMode.wrappedValue.dismiss() }) {Text("Go to ContentView")}
        }.navigationBarTitle("ViewA")
    }
}

struct ViewB: View {
    @Environment(\.presentationMode) var presentationMode
    var body: some View {
        VStack {
            Text("Go Home")
            NavigationLink(destination: ContentView()) {Text("Go")}
            Text("Go back")
            Button(action: { self.presentationMode.wrappedValue.dismiss() }) {Text("Go to ViewB")}
        }.navigationBarTitle("ViewB")
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

在“旧”Swift 中,我可以轻松地进行 unwindSegue 类似

@IBAction func unwindToVCMain(segue:UIStoryboardSegue) { }
}

并轻松地称之为

performSegue(withIdentifier: "unwindToVcMain", sender: nil)

在iOS16及以上版本

新的编程导航方式非常强大!比旧的好多了。
新方法是使用NavigationStack(path:root).
路径参数是一个绑定到NavigationPath. ex.

@State private var path = NavigationPath()
    var body: some View {
        NavigationStack(path: $path) {
           ...
    }

让我们创建两个结构来说明它是如何工作的。

struct Fruit: Hashable,Identifiable {
    let id = UUID()
    var name: String
    var number: Int
    static var sample = [Fruit(name: "Apple", number: 2), Fruit(name: "Cherry", number: 3)]
}

struct Vegetable: Hashable,Identifiable {
    let id = UUID()
    var name: String
    var number: Int
    static var sample = [Vegetable(name: "Carrot", number: 2), Vegetable(name: "Zucchini", number: 3)]
}

新的导航风格是数据驱动的。
我在这里创建标签和链接...NavigationLink(value:label:)
但如果我有水果或蔬菜,目的地就会不同。

 .navigationDestination(for: Fruit.self) { fruit in
     VStack {
     ...
     }

因此,如果我有蔬菜或水果模型,根据链接中选择的数据类型,导航目的地将会不同,并且会呈现不同的视图。

因此,让我们将其放入 NavigationStack 中。让我们从 NavigationLink 开始:

Form {
    Section("Fruits") {
       ForEach(Fruit.sample) { fruit in
          NavigationLink(value: fruit) {
               HStack {
                 Text("\(fruit.number)")
                 Text(fruit.name)
               }
           }
       }
    }
    Section("Veggies") {
        ForEach(Vegetable.sample) { fruit in
           NavigationLink(value: fruit) {
                 HStack {
                   Text("\(fruit.number)")
                   Text(fruit.name)
                 }
             }
           }
         }
     }

Now the NavigationDestination看起来像这样:

 .navigationDestination(for: Fruit.self) { fruit in
     VStack {
         Text(fruit.name)
         HStack{
             let count = path.count
             Text("level: \(count)")
         }
         Form {
             Section("Veggies") {
                 ForEach(Vegetable.sample) { veg in
                     NavigationLink(value: veg) {
                         HStack {
                             Text("\(veg.number)")
                             Text(veg.name)
                         }
                     }
                 }
             }
         }
         Button("Unwind") {
             path.removeLast(path.count)
         }
     }

下面再次添加相同的内容,但对于蔬菜,例如:

.navigationDestination(for: Vegetable.self) { veg in
         VStack {
                   ...
}

现在,您可以从一个列表导航到另一个列表,应用程序将根据路径中收集的项目数量显示您的深度。然后你就可以放松了。这会将路径属性重置为空,并且将再次显示起始页!

屏幕将如下所示...以及展开按钮

并导航...

我希望这有帮助!

适用于 iOS 15 及以下版本

使用旧的NavigationView and NavigationLink(destination:isactive:label)

首先,将您的第一个视图嵌入导航控制器中。

然后插入下一个视图的导航链接。 NavigationLink 有不同的初始化程序。 选择这个isActive范围:

一开始有点令人费解,但isActive中的参数NavigationLink变成true单击链接时,导航将移至下一个屏幕。

它创建一个实例,在活动时显示目的地

如果我传递一个跟踪该属性状态的绑定,如果在后续视图链中的任何时候我再次将其设置为 false,它将重置并返回到原始屏幕!还蛮整齐的!!

请参阅代码中的这个简短示例:

struct ContentView: View {
    @State private var isActive: Bool = false

    var body: some View {
        NavigationView {
            NavigationLink(
                destination: SecondView(isActive: $isActive),
                isActive: $isActive,
                label: {
                    Text("Go to second View")
                })
                .navigationTitle("MainView")
        }
    }
}

我的第二个观点:

struct SecondView: View {
    @Binding var isActive: Bool

    var body: some View {
            NavigationLink("Go to Third View",destination:  ThirdView(isActive: $isActive))
                .navigationTitle("Second View")
    }
}

这里是放松的按钮,但它可以在任何视图中。 环境isActive = false这里有一些魔法!

struct ThirdView: View {
    @Binding var isActive: Bool

    var body: some View {
        Button("Unwind!"){
            isActive = false
        }
        .navigationTitle("Last View!")
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何放松到 SwiftUI 中的 MainView 的相关文章

随机推荐