使用CoreData保存数据后跳转至其他视图的实现方案求助
问题分析与解决方案
首先,你遇到的Thread 1: "executeFetchRequest:error: A fetch request must have an entity."错误和导航组件本身无关,是SetView中Core Data的Fetch Request配置错误导致的——要么是创建FetchRequest时没指定实体,要么是实体名称和Data Model中的定义不匹配。先解决这个Core Data问题,再用iOS 16+推荐的导航方式实现跳转。
一、先修复Core Data错误
检查SetView中的FetchRequest代码:
- 错误示例(未指定实体):
@FetchRequest() var cards: FetchedResults<Card> - 正确写法(指定实体+排序规则):
// 方式1:显式指定实体 @FetchRequest(entity: Card.entity(), sortDescriptors: [NSSortDescriptor(keyPath: \Card.term, ascending: true)]) var cards: FetchedResults<Card> // 方式2:使用Xcode自动生成的实体类,更简洁 @FetchRequest(sortDescriptors: [SortDescriptor(\.term)]) var cards: FetchedResults<Card>
同时确保:
- 实体类名(比如
Card)和Data Model文件中的实体名称完全一致(大小写敏感); SetView已通过环境变量获取正确的上下文:@Environment(\.managedObjectContext) private var viewContext
二、iOS 16+ 导航实现方案
方案1:使用navigationDestination修饰符(推荐)
这是iOS 16+官方推荐的导航方式,替代旧版NavigationLink(isActive:):
NavigationStack { List { ForEach(viewModel.termdefpairs.indices, id: \.self) { index in TermView(term: $viewModel.termdefpairs[index].term, definition: $viewModel.termdefpairs[index].definition, tag: $viewModel.termdefpairs[index].tag) } } .navigationBarItems(trailing: Button(action: { // 保存数据到Core Data for testForm in viewModel.termdefpairs { dataController.add(term: testForm.term, name: name, definition: testForm.definition, tag: testForm.tag, context: managedObjectContext) } // 触发跳转 isShowingSet = true // 若当前视图是弹出的sheet,保留dismiss();否则可移除 // dismiss() }) { Text("Save") }) // 绑定导航触发状态,指定目标视图 .navigationDestination(isPresented: $isShowingSet) { SetView() } }
方案2:传递数据的导航(适合需要给SetView传参的场景)
如果需要把保存后的闪卡集合数据直接传递给SetView,可以用navigationDestination(for:):
先定义可哈希的模型(用于导航标识):
struct FlashcardSet: Hashable { var name: String var cards: [TermDefPair] // 你的术语-定义配对模型 }在当前视图中实现:
@State private var selectedSet: FlashcardSet? NavigationStack { List { ForEach(viewModel.termdefpairs.indices, id: \.self) { index in TermView(term: $viewModel.termdefpairs[index].term, definition: $viewModel.termdefpairs[index].definition, tag: $viewModel.termdefpairs[index].tag) } } .navigationBarItems(trailing: Button(action: { // 创建闪卡集合模型 let newSet = FlashcardSet(name: name, cards: viewModel.termdefpairs) // 保存到Core Data for testForm in viewModel.termdefpairs { dataController.add(term: testForm.term, name: name, definition: testForm.definition, tag: testForm.tag, context: managedObjectContext) } // 触发跳转并传递数据 selectedSet = newSet }) { Text("Save") }) // 指定接收FlashcardSet类型的导航目标 .navigationDestination(for: FlashcardSet.self) { set in SetView(selectedSet: set) } }在
SetView中接收参数:struct SetView: View { let selectedSet: FlashcardSet @Environment(\.managedObjectContext) private var viewContext // ... 视图代码 }
内容的提问来源于stack exchange,提问作者syphixy
相关产品推荐
相关产品推荐

