Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 删除核心数据对象时关闭导航视图_Swift_Macos_Core Data_Swiftui - Fatal编程技术网

Swift 删除核心数据对象时关闭导航视图

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 {

我正在尝试使用SwiftUI和CoreData构建macOS应用程序。此应用程序的主窗口有一个
导航视图
,其中列表项绑定到提取请求,选择这些项中的任何一项都会填充详细视图。导航视图有点像这样:

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
    方法删除当前选定的对象
  • 子视图注意到其模型对象正在被删除
  • → 子视图调用PresentationMode.Dislose()
  • 第三步是我正在努力解决的问题。到目前为止,在核心数据类之上不使用视图模型类的情况下,一切都很顺利,但我觉得在试图弄清楚如何让子视图调用
    discouse()
    时遇到了麻烦。这需要从细节视图中进行,因为它从环境中获取
    PresentationMode
    ,而
    NavigationView
    会更改它

    虽然我可以通过
    @ObservedObject
    获得模型的
    isDeleted
    属性的
    绑定
    ,但我不知道我实际如何应对这种变化<代码>绑定似乎在暗中使用发布者,但它们不会公开一个发布者,例如,我可以通过发布连接到该发布者

    KVO over
    isDeleted
    可能是可能的,但从值类型进行监听并不好;没有好的地方可以删除观察器,如果应用程序运行太长时间,可能会出现问题

    这类问题的指导原则是什么?

    这是我的解决方案

    这是我的
    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){
    按钮(操作:{