Swift 删除核心数据对象时关闭导航视图
我正在尝试使用SwiftUI和CoreData构建macOS应用程序。此应用程序的主窗口有一个Swift 删除核心数据对象时关闭导航视图,swift,macos,core-data,swiftui,Swift,Macos,Core Data,Swiftui,我正在尝试使用SwiftUI和CoreData构建macOS应用程序。此应用程序的主窗口有一个导航视图,其中列表项绑定到提取请求,选择这些项中的任何一项都会填充详细视图。导航视图有点像这样: NavigationView { VStack(spacing: 0) { List(fetchRequest) { DetailRow(model: $0) } .listStyle(SidebarListStyle()) HStack {
导航视图
,其中列表项绑定到提取请求,选择这些项中的任何一项都会填充详细视图。导航视图有点像这样:
NavigationView {
VStack(spacing: 0) {
List(fetchRequest) { DetailRow(model: $0) }
.listStyle(SidebarListStyle())
HStack {
Button(action: add) { Text("+") }
Button(action: remove) { Text("-") }
}
}
Text("Select a model object")
}.navigationViewStyle(DoubleColumnNavigationViewStyle())
DetailRow
是一个NavigationLink
,它还定义了详细视图:
NavigationLink(destination: ModelDetail(model: model)) {
Text(model.name)
}
我认为modeldeail
的内容不是很重要;不管怎样,我都很灵活
在导航视图中,调用remove
方法的“-”按钮应删除当前选定的模型对象,并返回默认的空局部视图。不幸的是,我正在努力想出正确的方法来做到这一点。我相信我需要以下互动:
remove
方法删除当前选定的对象discouse()
时遇到了麻烦。这需要从细节视图中进行,因为它从环境中获取PresentationMode
,而NavigationView
会更改它
虽然我可以通过@ObservedObject
获得模型的isDeleted
属性的绑定
,但我不知道我实际如何应对这种变化<代码>绑定似乎在暗中使用发布者,但它们不会公开一个发布者,例如,我可以通过发布连接到该发布者
KVO overisDeleted
可能是可能的,但从值类型进行监听并不好;没有好的地方可以删除观察器,如果应用程序运行太长时间,可能会出现问题
这类问题的指导原则是什么?这是我的解决方案
这是我的NoteDetailView
。它允许从此视图或导航层次结构中的“主”视图中删除。此解决方案适用于Mac、iPad和iPhone
我向我的实体添加了可选的dateDeleted
。删除记录时,我只需向该属性添加一个值Date()
,然后保存上下文。在我的FetchRequests中,我只是断言dateDeleted=nil
。稍后,我将在我的应用程序中添加一个垃圾桶和其他东西,这样人们可以查看或永久清空他们的垃圾
然后我使用一个状态变量和一个通知来清除我的视图。您可以更改所需功能的代码:
struct NoteDetailView: View {
var note: Note
@Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
@Environment(\.managedObjectContext) var managedObjectContext
@State var noteBody: String = ""
@State var showEditNoteView: Bool = false
@State var showEmptyView: Bool = false
init(note: Note) {
self.note = note
self._noteBody = State(initialValue: note.body)
}
var body: some View {
VStack {
if (!showEmptyView) {
Text("NOT DELETED")
}
else {
EmptyView()
}
}
.navigationBarTitle(!showEmptyView ? note.title : "")
.navigationBarItems(trailing:
HStack {
if (!showEmptyView) {
Button(action: {
self.showEditNoteView.toggle()
}, label: {
NavBarImage(image: "pencil")
})
.sheet(isPresented: $showEditNoteView, content: {
EditNoteView(note: self.note).environment(\.managedObjectContext, self.managedObjectContext)
})
}
}
)
.onReceive(NotificationCenter.default.publisher(for: .NSManagedObjectContextDidSave)) { _ in
if (self.note.dateDeleted != nil) {
self.showEmptyView = true
self.presentationMode.wrappedValue.dismiss()
}
}
}
}
structNoteDetailView:视图{
var注:注
@环境(\.presentationMode)变量presentationMode:绑定
@环境(\.managedObjectContext)变量managedObjectContext
@状态变量noteBody:String=“”
@状态变量showEditNoteView:Bool=false
@状态变量showEmptyView:Bool=false
初始(注:注){
self.note=注释
self.\u noteBody=状态(初始值:note.body)
}
var body:一些观点{
VStack{
如果(!showEmptyView){
文本(“未删除”)
}
否则{
EmptyView()
}
}
.navigationBarTitle(!showEmptyView?注意。标题:“”)
.navigationBarItems(尾部:
HStack{
如果(!showEmptyView){
按钮(操作:{
self.showEditNoteView.toggle()
},标签:{
导航图像(图像:“铅笔”)
})
.sheet(显示:$showEditNoteView,内容:{
EditNoteView(注意:self.note).environment(\.managedObjectContext,self.managedObjectContext)
})
}
}
)
.onReceive(NotificationCenter.default.publisher(用于:.NSManagedObjectContextDidSave)){in
如果(self.note.dateDeleted!=nil){
self.showEmptyView=true
self.presentationMode.wrappedValue.discouse()文件
}
}
}
}
这是我的解决方案
这是我的NoteDetailView
。它允许从此视图或导航层次结构中的“主”视图中删除。此解决方案适用于Mac、iPad和iPhone
我向我的实体添加了可选的dateDeleted
。删除记录时,我只需向该属性添加一个值Date()
,然后保存上下文。在我的FetchRequests中,我只是断言dateDeleted=nil
。稍后,我将在我的应用程序中添加一个垃圾桶和其他东西,这样人们可以查看或永久清空他们的垃圾
然后我使用一个状态变量和一个通知来清除我的视图。您可以更改所需功能的代码:
struct NoteDetailView: View {
var note: Note
@Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
@Environment(\.managedObjectContext) var managedObjectContext
@State var noteBody: String = ""
@State var showEditNoteView: Bool = false
@State var showEmptyView: Bool = false
init(note: Note) {
self.note = note
self._noteBody = State(initialValue: note.body)
}
var body: some View {
VStack {
if (!showEmptyView) {
Text("NOT DELETED")
}
else {
EmptyView()
}
}
.navigationBarTitle(!showEmptyView ? note.title : "")
.navigationBarItems(trailing:
HStack {
if (!showEmptyView) {
Button(action: {
self.showEditNoteView.toggle()
}, label: {
NavBarImage(image: "pencil")
})
.sheet(isPresented: $showEditNoteView, content: {
EditNoteView(note: self.note).environment(\.managedObjectContext, self.managedObjectContext)
})
}
}
)
.onReceive(NotificationCenter.default.publisher(for: .NSManagedObjectContextDidSave)) { _ in
if (self.note.dateDeleted != nil) {
self.showEmptyView = true
self.presentationMode.wrappedValue.dismiss()
}
}
}
}
structNoteDetailView:视图{
var注:注
@环境(\.presentationMode)变量presentationMode:绑定
@环境(\.managedObjectContext)变量managedObjectContext
@状态变量noteBody:String=“”
@状态变量showEditNoteView:Bool=false
@状态变量showEmptyView:Bool=false
初始(注:注){
self.note=注释
self.\u noteBody=状态(初始值:note.body)
}
var body:一些观点{
VStack{
如果(!showEmptyView){
文本(“未删除”)
}
否则{
EmptyView()
}
}
.navigationBarTitle(!showEmptyView?注意。标题:“”)
.navigationBarItems(尾部:
HStack{
如果(!showEmptyView){
按钮(操作:{