修改EditView编辑视图
NewView新建身份卡视图基本完成了,我们再来到EditView编辑视图,同理,我们声明一个环境变量来管理对象上下文,如下代码所示:
@Environment(.managedObjectContext) var context @FetchRequest(entity: Model.entity(), sortDescriptors: [NSSortDescriptor(keyPath: \Model.id, ascending: false)]) var models: FetchedResults<Model>
对于编辑保存操作,我们也需要注释原有的代码,添加新的编辑更新方法,并修改EditView_Previews绑定关系,如下代码所示:
if let editItem = models.first(where: { $0.id == model.id }) { editItem.platformIcon = model.platformIcon editItem.title = model.title editItem.platformName = model.platformName editItem.indexURL = model.indexURL do { try context.save() self.presentationMode.wrappedValue.dismiss() } catch { let nsError = error as NSError fatalError("Unresolved error (nsError), (nsError.userInfo)") } }
上述代码中,由于我们需要编辑更新数据,因此首先要获得当前编辑数据的ID,我们通过判断当前ID与model(传输过来)中的数据做匹配,匹配成功后我们进行重新赋值,最后依旧调用save方法保存数据。
完成NewView新建页面和EditView编辑页面后,我们回到ContentView视图,首先是CardView视图,我们注释原有的viewModel视图模型相关内容,并且声明一个全局变量用于关联数据,如下代码所示:
@Environment(.managedObjectContext) var context var model: Model
然后修改打开编辑界面视图的绑定关系,并且先删除原先删除身份卡的方法,如下代码所示:
// 打开编辑弹窗 .sheet(isPresented: self.$showEditView, onDismiss: { self.showEditView = false }) { EditView(model: model) }
完成后,我们再来到ContentView的body视图,修改NewView绑定关系和CardView绑定关系,如下代码所示:
// 卡片视图 CardView(platformIcon: item.platformIcon, title: item.title, platformName: item.platformName, indexURL: item.indexURL,model: item)
上述代码做的事情比较绕,简单解释就是我们在NewView视图和NewView视图重新声明了相关属性或者变量,我们就需要在使用到这些视图或者跳转到这些视图的地方做数据的绑定,便于数据在页面之间传递。
模拟器效果预览
完成之后,我们发现操作了下模拟器,添加身份卡后还是没有数据,这是因为Contentview_preview结构体中注入托管对象上下文,我们给Contentview_preview结构体注入数据,我们先创建示例数据,如下代码所示:
// SwiftUI预览的测试配置 static var preview: Persistence = { let controller = Persistence(inMemory: true) // 示例数据 let newItem = Model(context: controller.container.viewContext) newItem.id = UUID() newItem.platformIcon = "icon_juejin" newItem.title = "签约作者" newItem.platformName = "掘金技术社区" newItem.indexURL = "juejin.cn/user/3897092103223517" return controller }()
然后加数据集加到Contentview_preview结构体中,如下代码所示:
ContentView().environment(.managedObjectContext, PersistenceController.preview.container.viewContext)