T. Karter
T. Karter

Reputation: 738

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

I have a ContentView with a TabView. When I add an item in the AddItemView and press the save button, I want to open the MyDataView. I already tried a NavigationLink but this shows a weird nested NavigationView. What can I do, to present the MyDataView after pressing the save button?

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"))
        }
    }
}
´´´

Upvotes: 0

Views: 1672

Answers (2)

Ludyem
Ludyem

Reputation: 1919

You can create an ObservableObject and use that to track the selected tab in your TabView, then you just need to pass it to all the views where you want to switch tab. Like this:

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

Upvotes: 1

Asperi
Asperi

Reputation: 257603

Here is a possible solution. Tested with Xcode 12.

Modified only components:

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

Upvotes: 2

Related Questions