Navigate inside master instead of detail in SplitView in SwiftUI

1.6k Views Asked by At

I have a split view in my iPad ready app:

struct ContentView: View {
    var body: some View {
        NavigationView {
            List {
                NavigationLink("Show the slave view HERE", destination: SlaveView())
                    .navigationBarTitle("Master view")
            }

            Text("Detail view")
                .navigationBarTitle("DO NOT show the slave view here")
        }
    }
}

So I like the SlaveView view to open in the list itself, not in the detail view. I have tried setting another NavigationView in the Slave, also a text below that, also setting all navigationViewStyles on both and each Master and Slave with no luck.

This is the simplest Slave view you can have to make it build:

struct SlaveView: View {
    var body: some View {
        List {
            NavigationLink("Sub Detail view", destination: Text("Sub Detail view"))
        }
        .navigationBarTitle("Slave view")
    }
}

So how can I change the Master (left) view of the split view instead of the detail (right) view?

Note that this is a simplified reproducible code. The real project uses more complex lists for master and slaves and so on. Also, we don't want to loos navigation stuff like transitions, title transforming, back button and etc.

For more clarifying, I need this state in the flow:

Needed step

3

There are 3 best solutions below

4
On BEST ANSWER

Just modify link that it is not a detail

demo

NavigationLink("Show the slave view HERE", destination: SlaveView())
    .isDetailLink(false)
3
On

You may try using a Button instead of a NavigationLink and replace your master view:

struct ContentView: View {
    @State var showSlaveView = false

    var body: some View {
        NavigationView {
            masterView
                .navigationBarTitle("Master view")
            Text("Detail view")
                .navigationBarTitle("DO NOT show the slave view here")
        }
    }
}

extension ContentView {
    @ViewBuilder
    var masterView: some View {
        if showSlaveView {
            SlaveView()
                .onTapGesture { self.showSlaveView = false }
        } else {
            Button("Show the slave view HERE") {
                self.showSlaveView = true
            }
        }
    }
}
1
On

You can try using StackNavigationViewStyle()

struct ContentView: View {
    var body: some View {
        NavigationView {
            NavigationLink("Show the slave view HERE", destination: SlaveView())
                .navigationBarTitle("Master view")
            
            Text("Detail view")
                .navigationBarTitle("DO NOT show the slave view here")
        }
        .navigationViewStyle(StackNavigationViewStyle())
    }
}