Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@pitt500
Created July 8, 2022 04:40
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pitt500/8bc7e2f6b35226b3c7df08501dbd0a8e to your computer and use it in GitHub Desktop.
Save pitt500/8bc7e2f6b35226b3c7df08501dbd0a8e to your computer and use it in GitHub Desktop.
import SwiftUI
struct ContentView: View {
@State var path = NavigationPath()
var body: some View {
NavigationStack(path: $path) {
List {
Section {
ForEach(Fruit.allCases) { fruit in
NavigationLink(fruit.name, value: fruit)
}
} header: { Text("Fruits") }
Section {
ForEach(Vegetable.allCases) { vegetable in
NavigationLink(vegetable.name, value: vegetable)
}
} header: { Text("Vegetables") }
}
.navigationTitle("Food")
.navigationDestination(for: Fruit.self) { fruit in
FruitView(fruit: fruit){ nextFruit in
NavigationLink(value: nextFruit) {
Text("Next \(nextFruit.rawValue)")
}
.buttonStyle(.plain)
}
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Button {
nextRandom()
} label: {
Text("Next Random")
.foregroundColor(.black)
}
}
}
}
.navigationDestination(for: Vegetable.self) { vegetable in
VegetableView(vegetable: vegetable){ nextVegetable in
NavigationLink(value: nextVegetable) {
Text("Next \(nextVegetable.rawValue)")
}
.buttonStyle(.plain)
}
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Button {
nextRandom()
} label: {
Text("Next Random")
.foregroundColor(.black)
}
}
}
}
}
}
func nextRandom() {
let value: any Hashable = Bool.random() ? Fruit.random : Vegetable.random
path.append(value)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
enum Fruit: String, Hashable, CaseIterable {
case banana = "🍌"
case orange = "🍊"
case peach = "πŸ‘"
case apple = "🍎"
static var random: Self {
Self.allCases.randomElement()!
}
var color: Color {
switch self {
case .banana:
return .yellow
case .orange:
return .orange
case .peach:
return .pink
case .apple:
return .red
}
}
var name: String {
switch self {
case .banana:
return "Banana"
case .orange:
return "Orange"
case .peach:
return "Peach"
case .apple:
return "Apple"
}
}
}
extension Fruit: Identifiable {
var id: String { self.rawValue }
}
enum Vegetable: String, Hashable, CaseIterable {
case tomato = "πŸ…"
case avocado = "πŸ₯‘"
case potato = "πŸ₯”"
case broccoli = "πŸ₯¦"
static var random: Self {
Self.allCases.randomElement()!
}
var color: Color {
switch self {
case .tomato:
return .red
case .avocado:
return .green
case .potato:
return .yellow
case .broccoli:
return .green
}
}
var name: String {
switch self {
case .tomato:
return "Tomato"
case .avocado:
return "Avocado"
case .potato:
return "Potato"
case .broccoli:
return "Broccoli"
}
}
}
extension Vegetable: Identifiable {
var id: String { self.rawValue }
}
struct FruitView<Link: View>: View {
let fruit: Fruit
var nextLink: ((Fruit) -> Link)? = nil
var body: some View {
ZStack {
fruit.color.opacity(0.2).ignoresSafeArea(.all)
VStack {
Text(fruit.rawValue)
.font(.system(size: 100))
.padding()
nextLink?(Fruit.random)
}
}
.navigationTitle("\(fruit.name)")
}
}
struct VegetableView<Link: View>: View {
let vegetable: Vegetable
var nextLink: ((Vegetable) -> Link)? = nil
var body: some View {
ZStack {
vegetable.color.opacity(0.2).ignoresSafeArea(.all)
VStack {
Text(vegetable.rawValue)
.font(.system(size: 100))
.padding()
nextLink?(Vegetable.random)
}
}
.navigationTitle("\(vegetable.name)")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment