Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
NavigationSplitView with default selection | SwiftUI WWDC 2022
//
// ContentView.swift
// NewNav
//
// Created by Egor Merkushev on 15.06.2022.
//
import SwiftUI
struct CustomColorCategory: Identifiable, Hashable, Equatable {
var id = UUID()
let colors: [CustomColor]
let name: String
}
struct CustomColor: Identifiable, Hashable {
var id = UUID()
let color: Color
let name: String
}
struct ContentView: View {
@Environment(\.horizontalSizeClass) var horizontalSizeClass
@State var colorsCategories: [CustomColorCategory] = [
CustomColorCategory(colors: [
CustomColor(color: .red, name: "red"),
CustomColor(color: .blue, name: "blue"),
CustomColor(color: .yellow, name: "yellow")
], name: "common"),
CustomColorCategory(colors: [
CustomColor(color: .cyan, name: "cyan"),
CustomColor(color: .mint, name: "mint"),
CustomColor(color: .accentColor, name: "accent")
], name: "specific"),
]
@State var selectedColorCategory: CustomColorCategory?
@State var selectedColor: CustomColor?
@State var pathCategory: NavigationPath = NavigationPath()
@State var pathColor: NavigationPath = NavigationPath()
var body: some View {
NavigationSplitView {
List(colorsCategories, selection: $selectedColorCategory) { category in
NavigationLink(value: category) { // does not work with List selection option, presents just for visual style of selection provided by Split View
Text(category.name)
}
}
.navigationTitle("Categories")
} content: {
NavigationStack(path: $pathCategory) {
if let category = selectedColorCategory ?? colorsCategories.first! {
List(category.colors, selection: $selectedColor) { color in
NavigationLink(value: color) {
HStack {
Rectangle()
.fill(color.color)
.frame(width: 20, height: 20)
Text(color.name)
}
}
}
.navigationTitle(category.name)
}
}
} detail: {
NavigationStack (path: $pathColor) {
if let color = selectedColor {
VStack {
Rectangle()
.fill(color.color)
.frame(width: 200, height: 200)
Text(color.name)
}
.navigationTitle(color.name)
} else {
EmptyView()
}
}
}
.navigationSplitViewStyle(.balanced)
.onChange(of: selectedColorCategory) { newValue in
if let category = newValue {
pathCategory = NavigationPath.init([category])
} else {
pathCategory.removeLast(pathCategory.count)
}
}
.onChange(of: pathCategory) { newValue in
pathColor.removeLast(pathColor.count)
selectedColor = nil
guard pathCategory.isEmpty else { return }
selectedColorCategory = nil
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment