如何使在 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")
}
}
我对编程还很陌生,环顾四周后我认为我可以在这里提问。我基本上需要在 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")
}
}