SwiftUI侧边栏更新时导航状态重置问题求助
问题解决:Core Data添加数据后保持导航状态不重置
当你向Core Data添加新条目时,@FetchRequest会检测到数据变化并刷新ContentView的列表,旧的NavigationView会因为视图重绘丢失导航状态,导致回到根目录。以下是两种可行的解决方案:
方案一:iOS16+ 使用NavigationStack(推荐)
NavigationStack支持通过selection绑定主动维护导航状态,即使列表刷新也不会丢失选中状态。修改代码如下:
import SwiftUI import CoreData struct ContentView: View { @Environment(\.managedObjectContext) private var viewContext @FetchRequest( sortDescriptors: [NSSortDescriptor(keyPath: \Item.timestamp, ascending: true)], animation: .default) private var items: FetchedResults<Item> // 存储选中的Item的ID,维护导航状态 @State private var selectedItemID: NSManagedObjectID? var body: some View { NavigationStack(selection: $selectedItemID) { List(selection: $selectedItemID) { NavigationLink("Add Item", value: nil) { AddItemView() } ForEach(items) { item in NavigationLink(value: item.objectID) { Text(item.timestamp!, formatter: itemFormatter) } } } // 根据选中ID显示对应详情 if let selectedID = selectedItemID, let item = try? viewContext.existingObject(with: selectedID) as? Item { Text("Item at \(item.timestamp!, formatter: itemFormatter)") } else { Text("Select an item") } } } } // AddItemView、AddItemDetailView代码保持不变
方案二:兼容iOS15及以下
通过手动保存选中的Item的ID,在列表刷新后重新恢复选中状态:
import SwiftUI import CoreData struct ContentView: View { @Environment(\.managedObjectContext) private var viewContext @FetchRequest( sortDescriptors: [NSSortDescriptor(keyPath: \Item.timestamp, ascending: true)], animation: .default) private var items: FetchedResults<Item> @State private var selectedItemID: NSManagedObjectID? @State private var isAddItemActive = false var body: some View { NavigationView { List { // 单独管理Add Item的导航状态 Button("Add Item") { isAddItemActive = true } ForEach(items) { item in NavigationLink( destination: Text("Item at \(item.timestamp!, formatter: itemFormatter)"), tag: item.objectID, selection: $selectedItemID ) { Text(item.timestamp!, formatter: itemFormatter) } } } .background( NavigationLink(isActive: $isAddItemActive) { AddItemView() } label: { EmptyView() } ) Text("Select an item") } } } // AddItemView、AddItemDetailView代码保持不变
方案二中,把"Add Item"改成Button配合隐藏的NavigationLink,避免它和Item的导航链接共享状态;同时用tag和selection绑定维护选中的Item,即使列表刷新,selectedItemID会保留,导航状态也会恢复。
内容的提问来源于stack exchange,提问作者kartbnb
相关产品推荐
相关产品推荐

