I'm trying to navigate to my 'home' view when the user clicks a button a few screens into the NavigationStack. My skeleton code is below and I can't figure out why it doesn't return to View1 after clicking the "Go Home" button on View3.
import Foundation
import SwiftUI
import SwiftData
@Model
final class Item {
var name: String
init(name: String = "") {
self.name = name
}
}
struct View1: View{
@Environment(\.modelContext) private var modelContext
@Query private var items: [Item]
@State private var navigationPath: NavigationPath = NavigationPath()
var body: some View {
NavigationStack(path: $navigationPath) {
List {
ForEach(items) { item in
NavigationLink {
View2(navigationPath: $navigationPath, item: item)
} label: {
Text(item.name)
}
}
}
}
}
}
struct View2: View{
@Binding var navigationPath: NavigationPath
@Bindable var item: Item
@State var isPresentingNewItemView: Bool = false
var body: some View{
Text(item.name)
.toolbar {
Button("Edit", action: editItem)
}
.sheet(isPresented: $isPresentingNewItemView) {
View3(navigationPath: $navigationPath, item: item)
}
}
func editItem() {
isPresentingNewItemView = true
}
}
struct View3: View{
@Environment(\.modelContext) private var modelContext
@Environment(\.dismiss) private var dismiss
@Binding var navigationPath: NavigationPath
@Bindable var item: Item
var body: some View{
Text(item.name)
Button("Go Home"){
NavigationLink("Home") {
View1()
}
dismiss()
navigationPath = NavigationPath()
}
}
}
#Preview {
do{
let config = ModelConfiguration(isStoredInMemoryOnly: true)
let container = try! ModelContainer(for: Item.self, configurations: config)
for i in 1..<10 {
let item = Item(name: "Example Item \(i)")
container.mainContext.insert(item)
}
return View1()
.modelContainer(container)
} catch {
fatalError("Failed to create model container.")
}
}
I'm a newbie when it comes to coding in general so any feedback on your thought process is appreciated.
To make your View3
"Go Home" button work,
try this approach using NavigationLink(..., value: ...)
and
a navigationDestination(...)
as shown in the example code.
struct View1: View {
@Environment(\.modelContext) private var modelContext
@Query private var items: [Item]
@State private var navigationPath = NavigationPath()
var body: some View {
NavigationStack(path: $navigationPath) {
List {
ForEach(items) { item in
NavigationLink("\(item.name)", value: item) // <--- here
}
}
.navigationDestination(for: Item.self) { item in // <--- here
View2(navigationPath: $navigationPath, item: item)
}
}
}
}
struct View2: View{
@Binding var navigationPath: NavigationPath
@Bindable var item: Item
@State var isPresentingNewItemView: Bool = false
var body: some View{
Text(item.name)
.toolbar {
Button("Edit", action: editItem)
}
.sheet(isPresented: $isPresentingNewItemView) {
View3(navigationPath: $navigationPath, item: item)
}
}
func editItem() {
isPresentingNewItemView = true
}
}
struct View3: View{
@Environment(\.modelContext) private var modelContext
@Environment(\.dismiss) private var dismiss
@Binding var navigationPath: NavigationPath
@Bindable var item: Item
var body: some View{
Text(item.name)
TextField("", text: $item.name) // <--- for testing
Button("Go Home"){ // <--- here
dismiss()
navigationPath = NavigationPath()
}
}
}