簡體   English   中英

可選鏈接 SwiftUI 文本字段中的綁定值

[英]Optional chaining the binding value in SwiftUI textfield

我有以下模型:

struct Food: Codable, Identifiable {
    var id = UUID()
    var name: String = ""
    var energy: Float?
    var water: Float?
    var macroProfile: MacronutrientProfile?
}

struct MacronutrientProfile: Codable {
    var carb: Float?
    var protein: Float?
    var fat: Float?
}

我正在嘗試將此模型實例的值綁定到TextField ,如下所示:

struct FoodEditView: View {
    @State var food: Food
    var body: some View {
        Form {
            Section(header: Text("Basics").fontWeight(.bold)) {
                HStack {
                    Text("Name")
                    Spacer()
                    TextField("Name", text: $food.name)
                    .multilineTextAlignment(.trailing)
                }
                HStack {
                    Text("Energy")
                    Spacer()
                    TextField("Calories", value: $food.energy, formatter: calorie)
                    .multilineTextAlignment(.trailing)
                    .keyboardType(.numberPad)
                }
                HStack {
                    Text("Water")
                    Spacer()
                    TextField("Grams", value: $food.water, formatter: gram)
                    .multilineTextAlignment(.trailing)
                    .keyboardType(.numberPad)
                }
            }
            .textCase(.none)
            Section(header: Text("Macronutrients").fontWeight(.bold)) {
                HStack {
                    Text("Carbohydrates")
                    Spacer()
                    TextField("Grams", value: $food.macroProfile?.carb, formatter: gram)
                    .multilineTextAlignment(.trailing)
                    .keyboardType(.numberPad)
                }
                HStack {
                    Text("Protein")
                    Spacer()
                    TextField("Grams", value: $food.macroProfile?.protein, formatter: gram)
                    .multilineTextAlignment(.trailing)
                    .keyboardType(.numberPad)
                }
                HStack {
                    Text("Fat")
                    Spacer()
                    TextField("Grams", value: $food.macroProfile?.fat, formatter: gram)
                    .multilineTextAlignment(.trailing)
                    .keyboardType(.numberPad)
                }
            }
            .textCase(.none)

鏈接macroProfile時,我很奇怪,一長串錯誤:

XCode 錯誤

我的問題是,當可選鏈接macroProfile而不是使用energywater時,我怎么會收到這些錯誤,這兩者也是可選值? 解決這個問題的最佳方法是什么?

當在Binding上使用“點鏈”語法時,它是創建Binding的快捷語法。 它沒有點語法通常擁有的“查找此事物的屬性”的相同語義。

所以$food.name不會解析food的綁定,然后引用它的屬性之一。 它將創建一個雙向的Binding<String>到食物的name屬性。

類似地,當您擁有$food.macroProfile ,該表達式的值是Binding<MacroNutrientProfile?> ... 將直接更改food的值的綁定(並且它可以更改的值是可選的)。 不是綁定$food后引用該對象的屬性之一的解析。

$food.macroProfile?.carb是無意義的,因為$food.macroProfileBinding<MacroNutrientProfile?>類型,它不是可選類型。 所以你會看到錯誤。

$food.name不是無意義的,因為它是一個Binding<String>並且您不會試圖將非可選值視為可選值。

更改它的一種方法是使用自定義綁定:

struct Food: Codable, Identifiable {
    var id = UUID()
    var name: String = ""
    var energy: Float?
    var water: Float?
    var macroProfile: MacronutrientProfile?
}

struct MacronutrientProfile: Codable {
    var carb: Float?
    var protein: Float?
    var fat: Float?
}

struct SomeView : View {
    @State var food: Food
    let gram = NumberFormatter()

    var body : some View {
        let carbBinding = Binding<Float?>(get: { food.macroProfile?.carb },
                                          set: { newValue in food.macroProfile?.carb = newValue })

        return HStack {
           Text("Carbohydrates")
           Spacer()
            TextField("Grams", value: carbBinding, formatter: gram)
           .multilineTextAlignment(.trailing)
           .keyboardType(.numberPad)
       }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM