问题描述
我对编程还很陌生,环顾四周后,我认为我有机会在这里问一下。我基本上需要在 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")
}
}