SwiftUI 中的自定义 TextField 键盘,带有 UIViewRepresentable

问题描述

我在 UIViewRepresentable 中使用自定义 UITextField,以拥有一个只有小数点和自定义键盘工具栏的文本字段。目标是向工具栏添加基本内容,例如插入减号、E 等……我见过很多只针对“完成”按钮的代码。我已经尝试将 insertText() 添加到按钮操作,但我认为没有调用协调器,因此文本没有更新。我想要的只是在光标位置插入自定义字符串的能力。

代码如下:

struct DataTextField: UIViewRepresentable {

private var placeholder: String
@Binding var text: String

 init(_ placeholder: String,text: Binding<String>) {
    self.placeholder = placeholder
    self._text = text
 }

 func makeUIView(context: Context) -> UITextField {
    let textfield = UITextField()
    textfield.keyboardType = .decimalPad
    textfield.delegate = context.coordinator
    textfield.placeholder = placeholder
    let toolBar = UIToolbar(frame: CGRect(x: 0,y: 0,width: textfield.frame.size.width,height: 44))
    let minusButton = UIBarButtonItem(title: "-",style: .plain,target: self,action: #selector(textfield.minusButtonTapped(button:)))
    let scientificButton = UIBarButtonItem(title: "E",action: #selector(textfield.scientificButtonTapped(button:)))
    toolBar.items = [minusButton,scientificButton]
    toolBar.setItems([minusButton,scientificButton],animated: true)
    textfield.inputAccessoryView = toolBar
    textfield.borderStyle = .roundedRect
    textfield.textAlignment = .right
    textfield.adjustsFontSizetoFitWidth = true
    return textfield
    
 }
    
func updateUIView(_ uiView: UITextField,context: Context) {
    uiView.text = text
}

 func makeCoordinator() -> Coordinator {
    Coordinator(self)
 }

 class Coordinator: NSObject,UITextFieldDelegate {
    var parent: DataTextField

 init(_ textField: DataTextField) {
    self.parent = textField
 }

 func textField(_ textField: UITextField,shouldChangeCharactersIn range: NSRange,replacementString string: String) -> Bool {
     if let currentValue = textField.text as Nsstring? {
         let proposedValue = currentValue.replacingCharacters(in: range,with: string) as String
         self.parent.text = proposedValue
     }
     return true
     }
   }
 }

extension  UITextField {
   @objc func minusButtonTapped(button:UIBarButtonItem) -> Void {
    insertText("-")
   }
    @objc func scientificButtonTapped(button:UIBarButtonItem) -> Void {
     insertText("E")
    }
}

以及问题的视频:

Keyboard issue,if I press a keyboard button after the minus,the minus keeps on the textfield.

解决方法

我发现这是一个 Swift 错误,如果文本不在数组中,它只会更新文本。 (就我而言,确实如此)经过数小时的尝试后,我发现调用 const currentState = useRecoilValue(currentRoutesViewState); useEffect(() => { // currentState changed. // save the current state },[currentState]) 然后更新该函数内的文本可使按钮按预期工作。

delegate?.textFieldDidBeginEditing?(self)

将此添加到 UIViewRepresentable 中的 Coordinator 类:

extension UITextField {
    @objc func minusButtonTapped(button: UIBarButtonItem) -> Void {
        insertText("-")
        delegate?.textFieldDidBeginEditing?(self)
    }
    @objc func scientificButtonTapped(button: UIBarButtonItem) -> Void {
        insertText("E")
        delegate?.textFieldDidBeginEditing?(self)
    }
}

调用 func textFieldDidEndEditing(_ textField: UITextField,reason: UITextField.DidEndEditingReason) { textField.resignFirstResponder() } func textFieldDidBeginEditing(_ textField: UITextField) { self.parent.text = textField.text! } 是必须的。如果不关闭键盘,应用程序将崩溃,因为在我的情况下,视图本身可以被关闭。