New in SwiftUI 4: NavigationSplitView

DevTechie Inc
Jun 24

Another new addition introduced in SwiftUI 4, as a part of Navigation API is NavigationSplitView.

NavigationSplitView is a view that presents views in two or three column layout, selections in leading columns controls the presentation in subsequent columns.

We can create a split view with two or three column layout, we will start with two column layout first.

Two Column Layout
For our example, we will start with a simple data structure.

struct DevTechieCourse: Identifiable, Hashable {
    let id = UUID()
    let name: String
    let details: String
}
We also need some sample data to play with. Let’s add actual video courses available at https://www.devtechie.com

extension DevTechieCourse {
    static var exampleData: [DevTechieCourse] {
        [
            .init(name: "Mastering SwiftUI 3", details: "Mastering SwiftUI 3"),
            .init(name: "DisneyPlus Clone in SwiftUI", details: "DisneyPlus Clone in SwiftUI"),
            .init(name: "Drawing App in SwiftUI", details: "Drawing App in SwiftUI"),
            .init(name: "Speech ToDo in UIKit", details: "Speech ToDo in UIKit"),
            .init(name: "Build Strava Clone in UIKit", details: "Build Strava Clone in UIKit"),
            .init(name: "Build Music Player", details: "Build Music Player")
        ]
    }
}
Now, we are ready for our split view. We need to create two State variables, one to hold list of courses and another to hold user’s selection from the list of courses in leading column.

In our example, leading column will render list of DevTechie video courses and upon selection of any of those courses, we will display details in the detail panel.

struct ContentView: View {
    @State private var courses = DevTechieCourse.exampleData
    @State private var selection: DevTechieCourse?
    
    var body: some View {
        NavigationSplitView {
            List(courses, selection: $selection) { course in
                Text(course.name).tag(course)
            }
        } detail: {
            Text(selection?.name ?? "Choose a course")
        }
        .navigationSplitViewStyle(.balanced)
    }
}
Build and run this on iPad:

Running this example on iPhone will give us classic stacked navigation AKA master detail view.

Notice that we are using new modifier called navigationSplitViewStyle with balanced value. There are few more options available. I would encourage you to try all of those.

We can also specify navigation title with the help of navigationTitle modifier.

struct ContentView: View {
    @State private var courses = DevTechieCourse.exampleData
    @State private var selection: DevTechieCourse?
    
    var body: some View {
        NavigationSplitView {
            List(courses, selection: $selection) { course in
                Text(course.name).tag(course)
            }
            .navigationTitle("DevTechie Courses")
        } detail: {
            Text(selection?.name ?? "Choose a course")
                
        }
        .navigationSplitViewStyle(.balanced)
        
    }
}
iPad:

iPhone:

Complete code for two column layout:

import SwiftUIstruct ContentView: View {
    @State private var courses = DevTechieCourse.exampleData
    @State private var selection: DevTechieCourse?
    
    var body: some View {
        NavigationSplitView {
            List(courses, selection: $selection) { course in
                Text(course.name).tag(course)
            }
            .navigationTitle("DevTechie Courses")
        } detail: {
            Text(selection?.name ?? "Choose a course")
                
        }
        .navigationSplitViewStyle(.balanced)
        
    }
}
struct DevTechieCourse: Identifiable, Hashable {
    let id = UUID()
    let name: String
    let details: String
}
extension DevTechieCourse {
    static var exampleData: [DevTechieCourse] {
        [
            .init(name: "Mastering SwiftUI 3", details: "Mastering SwiftUI 3"),
            .init(name: "DisneyPlus Clone in SwiftUI", details: "DisneyPlus Clone in SwiftUI"),
            .init(name: "Drawing App in SwiftUI", details: "Drawing App in SwiftUI"),
            .init(name: "Speech ToDo in UIKit", details: "Speech ToDo in UIKit"),
            .init(name: "Build Strava Clone in UIKit", details: "Build Strava Clone in UIKit"),
            .init(name: "Build Music Player", details: "Build Music Player")
        ]
    }
}
struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
Three Column Layout
For three columns layout, we need little more data so let’s build another data structure.

struct DevTechieCourseByCategory: Identifiable, Hashable {
    let id = UUID()
    let name: String
    let courses: [String]
}
We will also add some sample data in extension:

extension DevTechieCourseByCategory {
    static var exampleData: [DevTechieCourseByCategory] {
        [
            .init(name: "SwiftUI", courses: ["Mastering SwiftUI 3", "DisneyPlus Clone in SwiftUI", "Drawing App in SwiftUI"]),
            .init(name: "UIKit", courses: ["Speech ToDo in UIKit", "Build Strava Clone in UIKit", "Build Music Player"])
        ]
    }
}
Notice that this time around we have two values to display. We have course categories, within each category we have list of courses. We will display course’s name as the detail for demo purposes.

struct ContentView: View {
    @State private var categories = DevTechieCourseByCategory.exampleData
    @State private var selectedCategory: DevTechieCourseByCategory?
    @State private var selectedCourse: String?
    
    var body: some View {
        NavigationSplitView {
            List(categories, selection: $selectedCategory) { category in
                Text(category.name).tag(category)
            }
        } content: {
            List(selectedCategory?.courses ?? [], id: \.self, selection: $selectedCourse) { course in
                Text(course)
            }
        } detail: {
            Text(selectedCourse ?? "Choose a course")
        }
    }
    
}
This time, our navigation split view will have three sections, leading column for categories, next column will show all the courses within each category and the last column will show the detail.



With that we have reached the end of this article. Thank you once again for reading. Subscribe to our weekly newsletter at https://www.devtechie.com