Search code examples
swiftui-navigationlink

After entering the subview through NavigationLink, it automatically returns to the parent view


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.

enter image description here

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())

Solution

  • I don't know why this issue occurs with NavigationView, but when I replaced it with NavigationStack, everything worked fine.