SwiftUI TextField用.number格式为空崩溃:IntegerParseStrategy问题
SwiftData可选Int属性绑定TextField崩溃的解决方案
方法1:自定义绑定处理nil值
直接绑定SwiftData的可选Int属性会在初始值为nil且TextField获取焦点时触发解析崩溃,我们可以通过自定义绑定,把nil映射为占位值(比如0),提交时再根据输入情况转回nil:
struct AssetView: View { @Bindable var asset: Asset var body: some View { let costBinding = Binding( get: { asset.cost ?? 0 }, set: { newValue in asset.cost = newValue == 0 ? nil : newValue } ) TextField("realestate_cost_eg", value: costBinding, format: .number) .onSubmit { // 提交时校验,空输入强制设为nil if let currentText = UITextField.currentText, currentText.isEmpty { asset.cost = nil } } } } // 扩展UITextField方便获取当前输入文本 extension UITextField { static var currentText: String? { UIApplication.shared.sendAction(#selector(getter: UITextField.text), to: nil, from: nil, for: nil) as? String } }
方法2:本地@State变量中转
用本地非可选的@State变量作为TextField的绑定源,再和SwiftData的asset对象同步值:
struct AssetView: View { @Bindable var asset: Asset @State private var tempCost: Int = 0 var body: some View { TextField("realestate_cost_eg", value: $tempCost, format: .number) .onAppear { // 初始化时同步asset的值 tempCost = asset.cost ?? 0 } .onSubmit { // 提交时把值同步回asset,空输入对应0转nil asset.cost = tempCost == 0 ? nil : tempCost } .onChange(of: asset.cost) { _, newValue in // asset值变化时同步到本地变量 tempCost = newValue ?? 0 } } }
方法3:自定义可选值格式样式
自定义支持可选Int的ParseableFormatStyle,明确处理空输入和nil值,避免系统默认解析策略的崩溃:
struct OptionalIntFormatStyle: ParseableFormatStyle { typealias FormatInput = Int? typealias FormatOutput = String // 把可选Int转为显示文本,nil显示空字符串 func format(_ value: Int?) -> String { guard let value = value else { return "" } return NumberFormatStyle.number.format(value) } // 解析输入文本,空字符串返回nil,否则按数字解析 func parse(_ value: String) throws -> Int? { guard !value.isEmpty else { return nil } return try NumberFormatStyle.number.parse(value) } } // 在视图中使用自定义格式 struct AssetView: View { @Bindable var asset: Asset var body: some View { TextField("realestate_cost_eg", value: $asset.cost, format: OptionalIntFormatStyle()) } }
内容的提问来源于stack exchange,提问作者Kenny Wyland
相关产品推荐
相关产品推荐

