You’re already familiar with the basic usage of NavigationStack
, which allows us to create views like this one:
struct ContentView: View {
var body: some View {
NavigationView {
Text("Hello, world!")
.navigationTitle("Primary")
}
}
}
That works great on iPhone, but on iPad it's less than ideal – there we have much larger screens to deal with, and having one large view for navigation is a poor use of the space, and also creates quite a jarring experience when new views slide in all the way across.
In these situations, it's a better idea to use a different view for navigation, called NavigationSplitView
. This lets us specify either two or three columns of data to show side by side, and iPadOS takes care of showing or hiding them at the right times depending on the exact configuration.
Try it out with this simple code:
NavigationSplitView {
Text("Primary")
} detail: {
Text("Content")
}
When you launch the app what you see once again depends on your device and orientation:
iPadOS does two very clever things here.
First, regardless of your device orientation you'll see a button that shows or hides the primary view, so users can choose what layout they want.
Second, when you activate multi-tasking – if you bring a Safari window alongside, for example – you'll see our app's views adapt so that the Primary view is hidden, because the system recognizes the amount of free space has decreased.
SwiftUI automatically links the primary and secondary views, which means if you have a NavigationLink
in the primary view it will automatically load its content in the secondary view:
NavigationSplitView {
NavigationLink("Primary") {
Text("New view")
}
} detail: {
Text("Content")
}
There are some ways you can customize this split view's behavior.
For example, you can tell iOS to prefer to keep the primary view around when space is partially limited like this:
NavigationSplitView(columnVisibility: .constant(.all)) {
NavigationLink("Primary") {
Text("New view")
}
} detail: {
Text("Content")
.navigationTitle("Content View")
}
.navigationSplitViewStyle(.balanced)
That requests that all columns be shown in a balance style, and the result is that iPads in portrait mode will now show the primary view.
Tip: columnVisibility
is actually provided as a binding, so you could store your option in some state and update it dynamically.
Second, you can tell the system to prefer the detail view by default, which is helpful on iPhone where the primary view is selected as standard:
NavigationSplitView(preferredCompactColumn: .constant(.detail)) {
Again, you can use that with a binding, so you can change it as your app runs if you want.
Finally, although you can use .toolbar(.hidden, for: .navigationBar)
to hide the toolbar in your detail view, be careful because it will hide the button to toggle the sidebar!
Tip: You can even add a third view to NavigationSplitView
, which lets you create a sidebar. You’ll see these in apps such as Notes, where you can navigate up from from the list of notes to browse note folders. So, navigation links in the first view control the second view, and navigation links in the second view control the third view – it’s an extra level of organization for times when you need it.
SPONSORED Join a FREE crash course for mid/senior iOS devs who want to achieve an expert level of technical and practical skills – it’s the fast track to being a complete senior developer! Hurry up because it'll be available only until February 9th.
Sponsor Hacking with Swift and reach the world's largest Swift community!
Link copied to your pasteboard.