【问题标题】:Unwrapping Optional Entity展开可选实体
【发布时间】:2022-12-19 16:07:36
【问题描述】:

假设 Item 是一个 CoreData 实体:

struct ItemDetailView: View {
@Binding var item: Item?
@Binding var isEditing: Bool

var body: some View{
    if isEditing {
        TextField( "Name", text: Binding($item.data)! )
    }else{
        Text(item!.data!)
    }
}
}

错误: 可选类型 'Item?' 的值必须展开以引用已包装的基类型“Item”的成员“数据”


编辑所有代码:

import SwiftUI
import CoreData

struct ItemDetailView: View {
    @Binding var item: Item?
    @Binding var isEditing: Bool
    
    var body: some View{
        if isEditing {
            
            TextField( "Name", text: Binding($item.data)! )
        }else{
            Text(item!.data!)
        }
    }
}

struct ItemEditorView: View {
    @Environment(\.managedObjectContext) private var viewContext
    @Environment(\.dismiss) private var dismiss
    
    let isNew: Bool
    @State var isEditing: Bool = false
    @State var item: Item?
    @Binding var newItem: Item?
    
    
    var body: some View {
        
        if isNew {
                
        }
        
        NavigationView{
            ItemDetailView(item: isNew ? $newItem : $item, isEditing: $isEditing)
                .toolbar {
                    ToolbarItem {
                        Button(isNew ? "Add" : (isEditing ? "Done" : "Edit")) {
                            //TBI
                            if isNew {
                                
                            }
                        }
                    }
                    ToolbarItem(placement:.cancellationAction){
                        Button("Cancel"){
                            dismiss()
                        }
                    }
                }
                .navigationTitle("Item Editor")
        }
    }
}

struct ItemsListView: View {
    @Environment(\.managedObjectContext) private var viewContext
    @FetchRequest(
        sortDescriptors: [NSSortDescriptor(keyPath: \Item.data, ascending: true)],
        animation: .default)
    private var items: FetchedResults<Item>
    @State var presentNewItemEditorView = false
    @State var newItem: Item?
    
    var body: some View {
        NavigationView {
            VStack{
                Text(newItem?.data ?? "nil")
                List {
                    ForEach(items){ item in
                        NavigationLink(item.data!, destination: ItemEditorView(isNew: false, item:item, newItem: $newItem))
                    }
                }
            }
            .fullScreenCover(isPresented: $presentNewItemEditorView, content: {
                ItemEditorView(isNew: true, isEditing: true, newItem: $newItem)
            })
            .navigationTitle("Main")
            .toolbar {
                ToolbarItem {
                    Button("New goal"){
                        presentNewItemEditorView = true
                    }
                }
            }
            .task {
                newItem = Item(context: viewContext)
                newItem!.data = "New item text"
            }
        }
    }
}

【问题讨论】:

  • 为什么 item 是可选的? @Binding var item: Item 编译。顺便说一下,@Binding 是针对值类型的。核心数据实体可以/应该是边界作为@ObservableObject
  • 添加了所有代码以向您展示为什么 item 是可选的
  • 请观看this video 如何在 SwiftUI 中有效地使用核心数据来添加和编辑没有选项的项目。

标签: swiftui core-data


【解决方案1】:

我不清楚你想要达到什么目的。以下是将编译的选项。

值类型

struct Item {
    var data: String
}

struct ItemDetailView: View {
    @Binding var item: Item
    @Binding var isEditing: Bool
    
    var body: some View{
        if isEditing {
            TextField( "Name", text: Binding(projectedValue: $item.data) )
        }else{
            Text(item.data)
        }
    }
}

引用类型和值类型

class Item {
    var data: String? = ""
}

struct ItemDetailView: View {
    @Binding var item: Item? // Has no sense, because @Binding does't work with clsses!
    @Binding var isEditing: Bool
    
    var body: some View{
        if isEditing {
            TextField("Name", text: Binding(get: {
                item!.data!
            }, set: { value in
                item?.data = value
            }))
        } else {
            Text(item!.data!)
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-16
    • 2023-03-11
    • 2013-05-17
    • 2018-11-30
    • 1970-01-01
    • 2014-01-29
    相关资源
    最近更新 更多