SwiftUI中TextField绑定可选链式嵌套值报错原因及解决方法
问题原因
$food.energy对应的绑定类型是Binding<Float?>,绑定本身为非可选类型,仅绑定包裹的值是可选类型,正好匹配TextField的value参数要求的Binding<V?>类型,因此不会报错。
而$food.macroProfile?.carb通过可选链式调用生成的绑定类型是Binding<Float?>?,绑定本身为可选类型:当macroProfile为nil时,整个绑定会直接返回nil,而TextField不接受可选类型的绑定作为输入,因此触发编译错误。
最优修复方案
推荐通过自定义非可选绑定来自动处理macroProfile为空的场景,赋值时自动初始化空的MacronutrientProfile实例,无需修改原有模型定义,对业务逻辑侵入性最低:
struct FoodEditView: View { @State var food: Food // 自定义非可选的macroProfile绑定 var macroProfileBinding: Binding<MacronutrientProfile> { Binding( get: { food.macroProfile ?? MacronutrientProfile() }, set: { food.macroProfile = $0 } ) } 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: macroProfileBinding.carb, formatter: gram) .multilineTextAlignment(.trailing) .keyboardType(.numberPad) } HStack { Text("Protein") Spacer() TextField("Grams", value: macroProfileBinding.protein, formatter: gram) .multilineTextAlignment(.trailing) .keyboardType(.numberPad) } HStack { Text("Fat") Spacer() TextField("Grams", value: macroProfileBinding.fat, formatter: gram) .multilineTextAlignment(.trailing) .keyboardType(.numberPad) } } .textCase(.none) } } }
如果业务逻辑允许macroProfile为非可选类型,也可以直接修改模型定义,给macroProfile设置默认初始值var macroProfile: MacronutrientProfile = MacronutrientProfile(),直接用$food.macroProfile.carb绑定即可。
内容的提问来源于stack exchange,提问作者dsynkd
相关产品推荐
相关产品推荐

