关于核心数据对象更改的 SwiftUI 更新视图 [英] SwiftUI update view on core data object change

查看:33
本文介绍了关于核心数据对象更改的 SwiftUI 更新视图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到的问题是,当我从工作表视图更新核心数据资产对象时,更改未反映在 AssetListView 的 UI 中.(请注意,从工作表视图插入新对象确实刷新 AssetListView 的 UI.在工作表视图中删除对象也会刷新 AssetListView 的 UI)唯一不起作用的操作是更新.

The problem that I am having is that when I update a core data Asset object from a sheet view, the change is not reflected in the UI of the AssetListView. (Note that Inserting a new object from the sheet view does refresh the UI of the AssetListView. Deleting an object in sheet view also refreshes the UI of the AssetListView) The only action that is not working is the Update.

当核心数据对象发生变化时,如何让AssetListView发生变化?

How can I make the AssetListView change when the core data object changes?

我有以下 SwiftUI 代码显示来自 CoreData FetchRequest 的资产列表:

I have the following SwiftUI code showing a list of assets from a CoreData FetchRequest:

struct AssetListView: View {
    @State private var showingSheet = false
    @State private var selectedAssetId: NSManagedObjectID?
    @Environment(\.managedObjectContext) var moc
    @FetchRequest(entity: Asset.entity(), sortDescriptors: [NSSortDescriptor(keyPath: \Asset.allocationPercentage, ascending: false)]) var assets: FetchedResults<Asset>
    
    var body: some View {
        VStack {
            Form {
                 ForEach(assets, id: \.self) { asset in
                    Section {
                        AssetRowView(asset: asset)
                            .onTapGesture {
                                self.selectedAssetId = asset.objectID
                                self.showingSheet = true
                        }
                    }
                }
            }
            
        }
        .navigationBarTitle("Assets").sheet(isPresented: $showingSheet ) {
                EditAssetView(assetId: self.selectedAssetId!)
                    .environment(\.managedObjectContext, self.moc)
                }
        }
     }
}

这是一个编辑屏幕,我将其显示为 SwiftUI 表:

And this is an edit screen, which I present as SwiftUI sheet:

struct EditAssetView: View {
    var assetId: NSManagedObjectID
    @Environment(\.presentationMode) var presentationMode
    @State private var name = ""
    @State private var description = ""
    @Environment(\.managedObjectContext) var moc
    
    var asset: Asset {
        moc.object(with: assetId) as! Asset
    }
   
    var body: some View {
        NavigationView {
            Form {
                Section {
                    TextField("Name", text: $name)
                    TextField("Description", text: $description)
                }
            }
            .navigationBarTitle(Text("Edit Asset"), displayMode: .inline)
            .navigationBarItems(leading: Button("Cancel") {
                self.presentationMode.wrappedValue.dismiss()
                }, trailing: Button("Done") {
                    self.presentationMode.wrappedValue.dismiss()
                    self.asset.name = self.name
                    self.asset.assetDescription = self.description
                    try? self.moc.save()
                }
            )
        }
        .onAppear {
            self.name = self.asset.name
            self.description = self.asset.assetDescription
        }
    }
}

这是 AssetRowView 的代码:

Here is the code for AssetRowView:

struct AssetRowView: View {
    var asset: Asset?
    
    var body: some View {
        HStack {
           Text(asset.name)
           Text(asset.assetDescription)
        }
    }
}

推荐答案

Try to observe Asset (cause NSManagedObject is-a ObservableObject)

Try to observe Asset (cause NSManagedObject is-a ObservableObject)

struct AssetRowView: View {
    @ObservedObject var asset: Asset        // << here !!
    
    var body: some View {
        HStack {
           Text(asset.name)
           Text(asset.assetDescription)
        }
    }
}

如果这还不够,还可能需要将 Done 按钮操作更新为

if that will not be enough, also might be needed to update Done button action as

}, trailing: Button("Done") {
    self.asset.objectWillChange.send()             // << here !!
    self.asset.name = self.name
    self.asset.assetDescription = self.description
    try? self.moc.save()

    // better do this at the end of activity
    self.presentationMode.wrappedValue.dismiss()
}

这篇关于关于核心数据对象更改的 SwiftUI 更新视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆