SwiftUI嵌套NavigationLink异常问题排查求助
我使用LazyGrid展示列表项,点击元素需跳转到编辑页面,但出现以下问题:
- 最初在ForEach中使用包含目标页的NavigationLink时,目标视图会在点击前就为每个元素完成初始化;点击后进入无限循环。移除目标视图的ViewModel后,初始化次数变为
2*cList.count次。 - 改用
navigationDestination方案后,点击时目标视图会初始化cList.count次,且几乎立即自动返回,控制台报错:"A navigationDestination for “PEM.Category” was declared earlier on the stack. Only the destination declared closest to the root view of the stack will be used."
视图代码
import SwiftUI struct ContentView2: View { @ObservedObject var etvm: EditTransactionViewModel var body: some View { NavigationStack { VStack{ Form { Section(header: Text("Main").font(.subheadline)){ NavigationLink() { InnerListView2(selectedCategory: .constant(nil)) } label: { Text("Row") } .isDetailLink(false) .navigationTitle("Outer List") } } } } } } struct InnerListView2: View { @FetchRequest ( entity: Category.entity(), sortDescriptors: [NSSortDescriptor(keyPath: \Category.name, ascending: true)], predicate: NSPredicate(format: "rootCategory == nil") ) private var cList: FetchedResults<Category> @Binding var selectedCategory: Category? var body: some View { Form { Section(header: Text("Root Categories").font(.subheadline)) { ScrollView { LazyVGrid(columns: [GridItem(.flexible())], spacing: 20) { ForEach(cList, id: \.self) { c in // OPTION 2 NavigationLink(value: c) { // SelectableCategoryView(category: c, showEdit: true) // } NavigationLink(destination: InnerInnerListView2(ecvm: .init(category: c))) { SelectableCategoryView(category: c, showEdit: true) } .isDetailLink(false) .navigationTitle("Inner List") } } // OPTION 2 .navigationDestination(for: Category.self) { c in // InnerInnerListView2(ecvm: .init(category: c) // } } } } } } struct InnerInnerListView2: View { @ObservedObject var ecvm: EditCategoryViewModel var body: some View { Text("Row \(ecvm.wrappedCat.iconName) " ) } } struct ContentView2_Previews: PreviewProvider { static var previews: some View { ContentView2(etvm: .init()) } }
ViewModel代码
@MainActor class EditCategoryViewModel: ObservableObject { var storedCat: Category? @Published var wrappedCat: InputCatModel @Published var hasError = false let isNew: Bool private let provider = PersistenceController.shared init(category: Category? = nil, in context: NSManagedObjectContext = PersistenceController.shared.container.viewContext) { print("Eccomi") self.storedCat = category if let category, let existingObj = provider.exisits(category, in: context) as? Category { self.wrappedCat = .init(category: existingObj) self.isNew = false } else { self.wrappedCat = .init() self.isNew = true } } }
测试代码
@main struct testApp: App { let persistenceController = PersistenceController.shared var body: some Scene { WindowGroup { ContentView2(etvm: .init()) .environment(\.managedObjectContext, persistenceController.container.viewContext) .onAppear(perform: { setDefCategories(persistenceController.container.viewContext) }) } func setDefCategories(_ viewContext: NSManagedObjectContext) { // MARK: Root Category let e1 = Category(context: viewContext) e1.name = "Generico" e1.icon = "cart" e1.isIncome = false e1.rootCategory = nil e1.colorId = "IconColor1" let e2 = Category(context: viewContext) e2.name = "Spesa ed Alimenti" e2.icon = "cart" e2.isIncome = false e2.rootCategory = nil e2.colorId = "IconColor2" } }
内容的提问来源于stack exchange,提问作者FeroX
相关产品推荐
相关产品推荐

