SwiftUI中如何传递@State变量至函数实现TextField验证复用
复用TextField数字/单标点验证方法的实现方案
你遇到的问题是原validateField方法硬编码了textFieldOne,无法复用,且传参时混淆了String值与Binding<String>绑定类型。只需调整方法参数类型并修改内部逻辑,就能实现多字段复用:
步骤1:修改验证方法,接收Binding参数
将validateField改为接受Binding<String>参数,用wrappedValue访问/修改绑定对应的@State变量,替代原硬编码的textFieldOne:
func validateField(_ field: Binding<String>, newValue: String) { let periodCount = newValue.components(separatedBy: ".").count - 1 let commaCount = newValue.components(separatedBy: ",").count - 1 if newValue.last == "." && periodCount > 1 || newValue.last == "," && commaCount > 1 { // 移除多余的句点/逗号 field.wrappedValue = String(newValue.dropLast()) } else { let filtered = newValue.filter { "0123456789.,".contains($0) } if filtered != newValue { field.wrappedValue = filtered } } }
步骤2:在各TextField的onChange中调用方法
调用时传入带$前缀的绑定变量(而非变量本身),确保方法能正确修改对应@State值:
TextField("field one", text: $textFieldOne) .keyboardType(.decimalPad) .onChange(of: textFieldOne) { newValue in validateField($textFieldOne, newValue: newValue) } TextField("field two", text: $textFieldTwo) .keyboardType(.decimalPad) .onChange(of: textFieldTwo) { newValue in validateField($textFieldTwo, newValue: newValue) }
完整修改后的代码
struct TextFieldNumbersOnly: View { @State private var textFieldOne = "" @State private var textFieldTwo = "" var body: some View { Form{ TextField("field one", text: $textFieldOne) .keyboardType(.decimalPad) .onChange(of: textFieldOne){newValue in validateField($textFieldOne, newValue: newValue) } TextField("field two", text: $textFieldTwo) .keyboardType(.decimalPad) .onChange(of: textFieldTwo){newValue in validateField($textFieldTwo, newValue: newValue) } } } func validateField(_ field: Binding<String>, newValue: String) { let periodCount = newValue.components(separatedBy: ".").count - 1 let commaCount = newValue.components(separatedBy: ",").count - 1 if newValue.last == "." && periodCount > 1 || newValue.last == "," && commaCount > 1 { field.wrappedValue = String(newValue.dropLast()) } else { let filtered = newValue.filter { "0123456789.,".contains($0) } if filtered != newValue { field.wrappedValue = filtered } } } }
报错原因说明
之前的错误是因为你传入了textFieldOne(String类型的值),但方法需要的是Binding<String>类型的绑定对象,正确传参必须使用带$前缀的$textFieldOne或$textFieldTwo。
内容的提问来源于stack exchange,提问作者fs_tigre
相关产品推荐
相关产品推荐

