如何使用 SwiftUI 中的按钮向后导航一个视图

How can I navigate one view back with a button in SwiftUI

我有一个 ContentView 和一个 TabView。当我在 AddItemView 中添加一个项目并按下保存按钮时,我想打开 MyDataView。我已经尝试过 NavigationLink,但这显示了一个奇怪的嵌套 NavigationView。按保存按钮后要显示 MyDataView 怎么办?

struct ContentView: View {
    var body: some View {
        TabView() {
            MyDataView()
                .tabItem {
                    Image(systemName: "chevron.down.circle.fill")
                    Text("My Data")
            }.tag(1)
            AddItemView()
                .tabItem {
                    Image(systemName: "chevron.up.circle")
                    Text("Add Item")
            }.tag(2)
        }
    }
}

struct AddItemView: View {
    var body: some View {
        NavigationView {
            Form {
                // My Form with textfields
                Button(action: {
                    //save
                }) {
                    Text("Add")
                }
            }
            .navigationBarTitle(Text("Add Item"))
        }
    }
}

struct MyDataView: View {
    var body: some View {
        NavigationView {
            List(["foo", "bar"], id: \.self) { item in
                Text(item)
            }
            .navigationBarTitle(Text("My Data"))
        }
    }
}
´´´

这是一个可能的解决方案。测试 Xcode 12.

仅修改的组件:

struct DDContentView: View {
    @State private var selection: Int = 1     // << here

    var body: some View {
        TabView(selection: $selection) {      // << here 
            MyDataView()
                .tabItem {
                    Image(systemName: "chevron.down.circle.fill")
                    Text("My Data")
            }.tag(1)
            AddItemView() { 
                  self.selection = 1      // in callback change selection
            }
                .tabItem {
                    Image(systemName: "chevron.up.circle")
                    Text("Add Item")
            }.tag(2)
        }
    }
}

struct AddItemView: View {
    var completion: () -> ()    // << here !!

    var body: some View {
        NavigationView {
            Form {
                // My Form with textfields
                Button(action: {
                    //save
                    self.completion()    // << callback !!
                }) {
                    Text("Add")
                }
            }
            .navigationBarTitle(Text("Add Item"))
        }
    }
}

您可以创建一个 ObservableObject 并使用它来跟踪您的 TabView 中选定的选项卡,然后您只需将它传递给您想要切换选项卡的所有视图。 像这样:

class AppState: ObservableObject {
    @Published var currentTab: Tab = .data
}

enum Tab {
  case data, item
}

struct ContentView: View {
    @ObservedObject var appState = AppState()
    
    @State var currentTab: Tab
    
    var body: some View {
        TabView(selection: $appState.currentTab) {
            MyDataView()
                .tabItem {
                    Image(systemName: "chevron.down.circle.fill")
                    Text("My Data")
                }.tag(Tab.data)
            AddItemView(appState: appState)
                .tabItem {
                    Image(systemName: "chevron.up.circle")
                    Text("Add Item")
            }.tag(Tab.item)
        }
    }
}

struct AddItemView: View {
    @ObservedObject var appState: AppState
    
    var body: some View {
        NavigationView {
            Form {
                // My Form with textfields
                Button(action: {
                    appState.currentTab = .data
                }) {
                    Text("Add")
                }
            }
            .navigationBarTitle(Text("Add Item"))
        }
    }
}

struct MyDataView: View {
    var body: some View {
        NavigationView {
            List(["foo", "bar"], id: \.self) { item in
                Text(item)
            }
            .navigationBarTitle(Text("My Data"))
        }
    }
}