将观察对象的投影值的属性传递给@Binding

Posted

技术标签:

【中文标题】将观察对象的投影值的属性传递给@Binding【英文标题】:Pass an observed object's projected value's property to @Binding 【发布时间】:2020-08-15 16:33:34 【问题描述】:

我有一个带有@FetchRequest 的主屏幕,它返回FetchResult<Item>。 In that main screen I have a list of all of the items with navigation links that, when selected, pass an Item to an ItemDetail view.在此ItemDetail 视图中,项目标有@ObservedObjectItemDetail 的子视图是 ItemPropertiesView,它列出了所有项目的属性。我使用$item.insert property here 将项目属性直接传递给ItemPropertiesView@Binding 属性。在 ItemPropertiesView 中,有几个 LineItem,我再次使用 $ 将属性传递给名为“value”的 @Binding 属性,该属性被传递到文本字段中,最终可以更改。

我的目标是能够编辑此文本字段,并且在您完成编辑后,能够将这些更改保存到我的核心数据存储中。

由于这有点难以阅读,这里是一个代码重现:

struct MainScreen: View 
    @FetchRequest(entity: Item.entity(), sortDescriptors: [NSSortDescriptor(key: "itemName", ascending: true)]) var items: FetchedResults<Item>
    var body: some View 
        NavigationView 
            List 
                ForEach(items, id: \.self)  (item: Item) in
                    NavigationLink(destination: ItemDetail(item: item)) 
                        Text(item.itemName ?? "Unknown Item Name")
                    
                 // ForEach
            
        
     // body
 // MainScreen

struct ItemDetail: View 
    @ObservedObject var item: Item

    var body: some View 
        ItemPropertiesView(itemCost: $item.itemCost)
    


struct ItemPropertiesView: View 
    @Binding var itemCost: String?

    var body: some View 
        LineItem(identifier: "Item Cost", value: $itemCost)
    


struct LineItem: View 
    let identifier: String
    @Binding var value: String

    var body: some View 
        HStack 
            Text(identifier).bold() + Text(": ")
            TextField("Enter value",text: $value)
        
    

我在 ItemDetail 中收到错误:“编译器无法在合理的时间内对该表达式进行类型检查;尝试将表达式分解为不同的子表达式”

这是我遇到的唯一错误。 我是 SwiftUI 新手,感谢所有反馈。

【问题讨论】:

【参考方案1】:

仅通过阅读代码,我认为问题出在ItemPropertiesView 中的可选属性中,只需将其删除即可

struct ItemPropertiesView: View 
    @Binding var itemCost: String      // << here !!
    // .. other code

并更新父级以桥接到 CoreData 模型可选属性

struct ItemDetail: View 
    @ObservedObject var item: Item

    var body: some View 
        let binding = Binding(
            get:  self.item.itemCost ?? "" ,
            set:  self.item.itemCost = $0 
        )
        return ItemPropertiesView(itemCost: binding)
    

【讨论】:

从那以后我了解到您可以将 Binding<_> 转换为 Binding<_>?使用其他 Binding init 之一。所以我所要做的就是 if let itemCost = Binding($itemCost) LineItem(...) in ItemPropertiesView 并且它按预期工作。

以上是关于将观察对象的投影值的属性传递给@Binding的主要内容,如果未能解决你的问题,请参考以下文章

以编程方式将投影内容传递给儿童? (否则将呈现为 <ng-content> )

Java方法中传递数组与改变数组值的问题

Java方法中传递数组与改变数组值的问题

如何将对象(或关联数组)作为属性值传递给我的 Web 组件

如何将属性传递给 Loader 创建的对象?

将实例传递给对象与稍后添加实例作为属性[关闭]