SwiftUI直接修改UITextField.text未同步更新绑定值如何解决
SwiftUI 编辑状态TextField手动改文本后绑定值不同步的解决办法
问题场景
开发中存在多个支持数字输入的TextField,用户可通过键盘输入,也可点击自定义工具栏的[+/-]按钮切换数值正负。直接修改editingTextField.text属性时,TextField的显示内容会正常更新,但绑定的@State变量不会同步更新,导致后续取值错误。
问题复现代码
import SwiftUI struct TestView: View { @State private var showTextFieldToolbar = false @State private var text = "" @State private var text2 = "" @State private var currentText = "" @State var editingTextField: UITextField? = nil var body: some View { ZStack { VStack { Text(currentText) TextField("Watts", text: $text , onEditingChanged: { editingChanged in } , onCommit: { showTextFieldToolbar = false }) .keyboardType(.decimalPad) .textFieldStyle(RoundedBorderTextFieldStyle()) .padding() TextField("Von", text: $text2) { isChanged in } onCommit: { showTextFieldToolbar = false } .keyboardType(.decimalPad) .textFieldStyle(RoundedBorderTextFieldStyle()) .padding() } .onReceive(NotificationCenter.default.publisher(for: UITextField.textDidBeginEditingNotification)) { obj in self.editingTextField = obj.object as? UITextField showTextFieldToolbar = true } .onChange(of: text, perform: { value in currentText = text }) .onChange(of: text2, perform: { value in currentText = text2 }) VStack { Spacer() if showTextFieldToolbar { HStack { Button("+/-") { plusMinusAction() } .foregroundColor(Color.black) .padding(.trailing, 12) Spacer() Button("OK") { showTextFieldToolbar = false editingTextField?.resignFirstResponder() } .foregroundColor(Color.black) .padding(.trailing, 12) } .frame(idealWidth: .infinity, maxWidth: .infinity, idealHeight: 44, maxHeight: 44, alignment: .center) .background(Color.gray) } } } } func plusMinusAction() { if let text = editingTextField?.text { if text.hasPrefix("-") { editingTextField?.text = String(text.suffix(text.count - 1)) } else { editingTextField?.text = "-\(text)" } } } } struct TestView_Previews: PreviewProvider { static var previews: some View { TestView() } }
解决方法
在TextField的onEditingChanged事件中手动同步绑定值即可解决问题,实现代码如下:
onEditingChanged: { isChanged in if !isChanged { text = editingTextField?.text ?? text editingTextField = nil } }
原理是当TextField结束编辑时,直接把修改后的UITextField文本赋值给绑定的@State变量,完成两者的同步。
内容的提问来源于stack exchange,提问作者Manh Khuc
相关产品推荐
相关产品推荐

