SwiftUI 文本字段中的可选链接绑定值
Posted
技术标签:
【中文标题】SwiftUI 文本字段中的可选链接绑定值【英文标题】:Optional chaining the binding value in SwiftUI textfield 【发布时间】:2021-11-06 04:31:12 【问题描述】:我有以下型号:
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
(这两个也是可选值)时,我怎么会得到这些错误?解决此问题的最佳方法是什么?
【问题讨论】:
使用自定义绑定:***.com/a/59642601/14733292 【参考方案1】:在Binding
上使用“点链接”语法时,它是创建Binding
的快捷语法。它与点语法通常具有的“查找此事物的属性”的语义不同。
所以$food.name
不会解决food
的绑定然后引用它的属性之一。它将为食物的name
属性创建双向Binding<String>
。
同样,当您拥有$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)
【讨论】:
谢谢!信息量很大。这回答了我问题的第一部分。现在,我该如何解决? 我添加了一个代码示例来演示一种方式。 真的没有更好的办法吗?这感觉有点麻烦。如果我的食物模型变得更大,我必须为每个嵌套对象创建一个自定义绑定。以上是关于SwiftUI 文本字段中的可选链接绑定值的主要内容,如果未能解决你的问题,请参考以下文章