You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.11 01:51:02