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

问题描述

我对编程还很陌生,环顾四周后,我认为我有机会在这里问一下。我基本上需要在 TextField 中输入的文本是不可删除的,尽管可以添加/输入其他文本。

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

我有一个基本的 TextField 设置,带有一个空的 Binding<String> 寻找我应该研究和/或学习的内容

谢谢。

解决方法

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

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 类并使用 UIViewRepresentable 与 SwiftUI 视图绑定。这样,您可以使用所有委托方法并检测退格。此外,使用它可以防止从点击操作中剪切和删除。

UndeletableTextField 自定义类

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