更新 UITextField.text 不会更新绑定值

时间:2021-07-21 09:13:51

标签: swiftui

我有多个 TextField 允许用户从键盘输入数字和从 [+/-] 按钮输入减号。问题是当我更新 [editingTextField.text] 的值时,Textfield 中的显示值已更新,但绑定值 [text] 未更新。我的 [+/-] 按钮如何更新当前编辑的 TextField?

感谢您的帮助!

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()
    }
}

编辑:我在 onEditingChanged 事件中更新了绑定值,它运行良好。

                      onEditingChanged: { isChanged in
                        if !isChanged {
                            text = editingTextField?.text ?? text
                            editingTextField = nil
                        }
                      }

1 个答案:

答案 0 :(得分:0)

编辑:

这是我用来使它工作的代码。也就是说,当单击 [+/-] 按钮时,text1 和 text2 值会更新。 (暂时忽略 currentText)

import SwiftUI


@main
struct TestApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

struct ContentView: View {
    var body: some View {
        TestView()
    }
}

class TextModel: ObservableObject {
    @Published var flag = false  // true="-", false=""
    @Published var text1 = ""
    @Published var text2 = ""
    
    func toggleUpdate() {
        flag.toggle()
        update()
    }
    
    func update() {
        if flag {
            text1 = text1.hasPrefix("-") ? text1 : "-" + text1
            text2 = text2.hasPrefix("-") ? text2 : "-" + text2
        } else {
            text1 = text1.hasPrefix("-") ? String(text1.dropFirst()) : text1
            text2 = text2.hasPrefix("-") ? String(text2.dropFirst()) : text2
        }
    }
}

struct TestView: View {
    
    @StateObject var textModel = TextModel()
    
    @State private var showTextFieldToolbar = false
    @State private var currentText = ""
    @State var editingTextField: UITextField? = nil
    
    var body: some View {
        ZStack {
            VStack {
                Text(currentText)
                TextField("Watts", text: $textModel.text1, onCommit: {
                    showTextFieldToolbar = false
                    currentText = textModel.text1
                })
                    .onTapGesture {
                        showTextFieldToolbar = true
                        currentText = textModel.text1
                        textModel.update()
                    }
                    .keyboardType(.decimalPad)
                    .textFieldStyle(RoundedBorderTextFieldStyle())
                    .padding()
                
                TextField("Von", text: $textModel.text2, onCommit: {
                    showTextFieldToolbar = false
                    currentText = textModel.text2
                })
                    .onTapGesture {
                        showTextFieldToolbar = true
                        currentText = textModel.text2
                        textModel.update()
                    }
                    .keyboardType(.decimalPad)
                    .textFieldStyle(RoundedBorderTextFieldStyle())
                    .padding()
            }
            .onReceive(NotificationCenter.default.publisher(for: UITextField.textDidBeginEditingNotification)) { obj in
                self.editingTextField = obj.object as? UITextField
                showTextFieldToolbar = true
            }
            
            VStack {
                Spacer()
                if showTextFieldToolbar {
                    HStack {
                        Button("+/-") {
                            plusMinusAction()
                        }
                        .foregroundColor(Color.black)
                        .padding(.trailing, 12)
                        Spacer()
                        Button("OK") {
                            textModel.update()
                            if let txt = editingTextField?.text {
                                currentText = txt
                            }
                            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 txt = editingTextField?.text {
            if txt.hasPrefix("-") {
                editingTextField?.text = String(txt.dropFirst())
            } else {
                editingTextField?.text = "-\(txt)"
            }
        }
        if let txt = editingTextField?.text {
            currentText = txt
        }
        textModel.toggleUpdate()
    }
    
}