如何使在 TextField 中键入的文本不可删除?

How to make text typed in TextField undeletable?

我对编程还很陌生,环顾四周后我认为我可以在这里提问。我基本上需要在 TextField 中输入的文本不可删除,尽管其他文本可以是 added/typed.

一种不同的方法是创建一个没有删除键的自定义键盘,尽管我在 SwiftUI 中找不到像研究等那样好的起点。

我有一个基本的 TextField 设置,其中有一个空的 Binding<String> 寻找我应该研究和/或学习的指针。

谢谢。

您可能需要该字符串的自定义绑定。以下是一个非常基本的示例——您可能想要涵盖更多边缘情况。请注意,我已选择将逻辑包含在 ObservableObject 中,但您可以通过将 _textStore 更改为 @State 变量来在 View 结构中执行相同的操作。您还希望包括初始文本等的逻辑。

class ViewModel : ObservableObject {

var _textStore = ""
var textBinding : Binding<String> { 
  Binding<String>(get: {
    return _textStore
  }, set: { newValue in
    //do something here to compare newValue to what existed before
    //note that this solution will allow text to be both prepended and appended to the existing text
    if _textStore.contains(newValue) { _textStore = newValue }
  })
}

}

...
@ObservedObject var vm = ViewModel()

TextField("", vm.textBinding)

想法是创建 UITextField class 并使用 UIViewRepresentable 与 SwiftUI 视图绑定。这样,您可以使用所有委托方法并检测退格键。此外,使用它可以防止通过点击操作进行剪切和删除。

UndeletableTextField 自定义 class

class UndeletableTextField: UITextField {

    // This for prevent to cut and delete
    override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
        if action == #selector(UIResponderStandardEditActions.delete(_:)) ||
            action == #selector(UIResponderStandardEditActions.cut(_:))  {
            return false
        }
        return super.canPerformAction(action, withSender: sender)
    }
}

UIViewRepresentable 视图

struct UndeletableTextFieldUI: UIViewRepresentable {
    
    @Binding var text: String
    var placeholder: String
    
    func makeUIView(context: Context) -> UndeletableTextField {
        let textField = UndeletableTextField(frame: .zero)
        textField.delegate = context.coordinator
        textField.placeholder = placeholder
        return textField
    }
    
    func updateUIView(_ uiView: UndeletableTextField, context: Context) {
        uiView.text = text
    }
    
    func makeCoordinator() -> Coordinator {
        Coordinator(parent: self)
    }
    
    class Coordinator: NSObject, UITextFieldDelegate {
        var parent: UndeletableTextFieldUI
        
        init(parent: UndeletableTextFieldUI) {
            self.parent = parent
        }
        
        func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
            // Here we detect backspace and ignore it.
            if let char = string.cString(using: String.Encoding.utf8) {
                let isBackSpace = strcmp(char, "\b")
                if (isBackSpace == -92) {
                    print("Backspace was pressed")
                    return false
                }
            }
            return true
        }
    }
}

内容视图

struct ContentView: View {
    @State private var text: String = ""
    var body: some View {
        UndeletableTextFieldUI(text: $text, placeholder: "Type here")
    }
}