I'm using SwiftUI's NavigationLink to build a view navigation. This navigation has three layers. When I enter the third-layer view, I can see that the view has been loaded, but the view automatically jumps back to the second-layer view. Xcode does not prompt any errors when running. I don't understand how this happened. I'm confused and can't think of what keywords to google.
I have attached the playground code that can reproduce this bug below. Please help me explain why this bug occurs and give me some ideas for modification. Thanks.
import PlaygroundSupport
import SwiftUI
class MyItem: Identifiable, Equatable {
static func == (lhs: MyItem, rhs: MyItem) -> Bool {
lhs.id == rhs.id
}
var id: String
var title: String
var parentId: String?
init(id: String, title: String, parentId: String?) {
self.id = id
self.title = title
self.parentId = parentId
}
}
class ViewModel: ObservableObject {
@Published var items: [MyItem] = []
@Published var parentItems: [MyItem] = []
init() {
fetchItmes()
}
private static let allItems: [MyItem] = {
var itemList: [MyItem] = []
for index in 0..<9 {
let listItem = MyItem(id: UUID().uuidString, title: "Title\(index)", parentId: nil)
itemList.append(listItem)
}
return itemList
}()
func fetchItmes() {
items = ViewModel.allItems
}
func fetchParentItems() {
parentItems = Array(ViewModel.allItems.prefix(3))
}
}
struct ContentView: View {
@StateObject var vm = ViewModel()
var body: some View {
NavigationView {
List {
ForEach(vm.items) { item in
NavigationLink(destination: DetailView(myItem: $vm.items[vm.items.firstIndex(of: item)!])) {
Text(item.title)
}
}
}
.navigationTitle("All Items")
}
.frame(width: 375, height: 667)
.environmentObject(vm)
}
}
struct DetailView: View {
@EnvironmentObject var vm: ViewModel
@Binding var myItem: MyItem
var body: some View {
VStack {
Text(myItem.title)
NavigationLink(destination: ParentItemList()) {
Text("Parent Item")
}
}
}
}
struct ParentItemList: View {
@EnvironmentObject var vm: ViewModel
var body: some View {
List {
ForEach(vm.parentItems) { item in
Text(item.title)
}
}
.onAppear {
vm.fetchParentItems()
}
}
}
PlaygroundPage.current.liveView = UIHostingController(rootView: ContentView())
I don't know why this issue occurs with NavigationView, but when I replaced it with NavigationStack, everything worked fine.