[英]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
時,我很奇怪,一長串錯誤:
我的問題是,當可選鏈接macroProfile
而不是使用energy
或water
時,我怎么會收到這些錯誤,這兩者也是可選值? 解決這個問題的最佳方法是什么?
當在Binding
上使用“點鏈”語法時,它是創建Binding
的快捷語法。 它沒有點語法通常擁有的“查找此事物的屬性”的相同語義。
所以$food.name
不會解析food
的綁定,然后引用它的屬性之一。 它將創建一個雙向的Binding<String>
到食物的name
屬性。
類似地,當您擁有$food.macroProfile
,該表達式的值是Binding<MacroNutrientProfile?>
... 將直接更改food
的值的綁定(並且它可以更改的值是可選的)。 它不是綁定$food
后引用該對象的屬性之一的解析。
$food.macroProfile?.carb
是無意義的,因為$food.macroProfile
是Binding<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.