Instantly share code, notes, and snippets.
Forked from Dimillian/NavigationSplitViewExample.swift
Created
July 18, 2023 05:30
-
Star
0
(0)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
-
Save hungeric/07b4cf78e6e0a84f5756d958a3c918e4 to your computer and use it in GitHub Desktop.
An example on how to use the new NavigationSplitView on iPad with global navigation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import SwiftUI | |
| enum HomeDestination: String, CaseIterable, Hashable { | |
| case hot, best, trending, new, top, rising | |
| } | |
| enum SubredditDestination: String, CaseIterable, Hashable { | |
| case news, diablo, pics, wtf, games, movies | |
| } | |
| enum UserDestination: String, CaseIterable, Hashable { | |
| case profile, inbox, posts, comments, saved | |
| } | |
| enum Destination: Hashable { | |
| case home(home: HomeDestination) | |
| case subreddit(subreddit: SubredditDestination) | |
| case user(user: UserDestination) | |
| case post(post: Post) | |
| } | |
| struct MainView: View { | |
| @State private var sidebarDestination: Destination = .subreddit(subreddit: .games) | |
| @State private var detailNavigation: Destination? | |
| var body: some View { | |
| NavigationSplitView { | |
| SidebarView(destination: $sidebarDestination) | |
| } content: { | |
| switch sidebarDestination { | |
| case .home(let destination): | |
| HomeView(destination: destination) | |
| case .subreddit(let subreddit): | |
| SubredditView(subreddit: subreddit, destination: $detailNavigation) | |
| case .user(let destination): | |
| AccountView(destination: destination) | |
| case .post(let post): | |
| PostView(post: post) | |
| } | |
| } detail: { | |
| NavigationStack { | |
| Group { | |
| if let detailNavigation { | |
| switch detailNavigation { | |
| case .post(let post): | |
| PostView(post: post) | |
| default: | |
| Text("Please select a post") | |
| } | |
| } else { | |
| Text("Please select a post") | |
| } | |
| }.navigationDestination(for: Destination.self) { destination in | |
| switch destination { | |
| case .user(let userDestination): | |
| AccountView(destination: userDestination) | |
| default: | |
| Text("Not supported here") | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| struct SidebarView: View { | |
| @Binding var destination: Destination | |
| var body: some View { | |
| List(selection: $destination) { | |
| Section("Home") { | |
| ForEach(HomeDestination.allCases, id: \.self) { homeItem in | |
| NavigationLink(value: Destination.home(home: homeItem)) { | |
| Label(homeItem.rawValue.capitalized, systemImage: "globe") | |
| } | |
| } | |
| } | |
| Section("Subreddit") { | |
| ForEach(SubredditDestination.allCases, id: \.self) { subreddit in | |
| NavigationLink(value: Destination.subreddit(subreddit: subreddit)) { | |
| Label(subreddit.rawValue.capitalized, systemImage: "globe") | |
| } | |
| } | |
| } | |
| Section("Account") { | |
| ForEach(UserDestination.allCases, id: \.self) { userDestination in | |
| NavigationLink(value: Destination.user(user: userDestination)) { | |
| Label(userDestination.rawValue.capitalized, systemImage: "globe") | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| struct Post: Identifiable, Hashable { | |
| let id = UUID() | |
| let title = "A post title" | |
| let preview = "Some wall of text to represent the preview of a post that nobody will read if the title is not a clickbait" | |
| } | |
| struct SubredditView: View { | |
| let subreddit: SubredditDestination | |
| @Binding var destination: Destination? | |
| @State private var posts: [Post] = [Post(), Post(), Post(), Post(), Post(), Post(), Post(), Post()] | |
| var body: some View { | |
| List(posts, selection: $destination) { post in | |
| NavigationLink(value: Destination.post(post: post)) { | |
| HStack { | |
| VStack(alignment: .leading) { | |
| Text(post.title) | |
| .font(.title3) | |
| .fontWeight(.semibold) | |
| Text(post.preview) | |
| .font(.callout) | |
| } | |
| } | |
| } | |
| }.navigationTitle(subreddit.rawValue.capitalized) | |
| } | |
| } | |
| struct PostView: View { | |
| let post: Post | |
| var body: some View { | |
| VStack { | |
| Text(post.title) | |
| .font(.title) | |
| Text(post.preview) | |
| NavigationLink(value: Destination.user(user: .comments)) { | |
| Text("See some sub navigation") | |
| } | |
| } | |
| } | |
| } | |
| struct AccountView: View { | |
| let destination: UserDestination | |
| var body: some View { | |
| Text(destination.rawValue.capitalized) | |
| } | |
| } | |
| struct HomeView: View { | |
| let destination: HomeDestination | |
| var body: some View { | |
| Text(destination.rawValue.capitalized) | |
| } | |
| } | |
| struct MainView_Previews: PreviewProvider { | |
| static var previews: some View { | |
| MainView() | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment