答案 0 :(得分:1)
是可以的,但是它需要继承UITextField
并创建自己的UIViewRepresentable
此答案基于Costantino Pistagna在他的medium article中所做的出色工作,但我们需要做更多的工作。
首先,我们需要创建UITextField
的子类,它也应符合UITextFieldDelegate
协议。
class WrappableTextField: UITextField, UITextFieldDelegate {
var textFieldChangedHandler: ((String)->Void)?
var onCommitHandler: (()->Void)?
var deleteHandler: (() -> Void)?
override func deleteBackward() {
super.deleteBackward()
deleteHandler?()
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
if let nextField = textField.superview?.superview?.viewWithTag(textField.tag + 1) as? UITextField {
nextField.becomeFirstResponder()
} else {
textField.resignFirstResponder()
}
return false
}
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)
textFieldChangedHandler?(proposedValue as String)
}
return true
}
func textFieldDidEndEditing(_ textField: UITextField) {
onCommitHandler?()
}
}
由于我们正在创建自己的TextField
实现,因此我们需要三个可用于回调的函数。
textFieldChangeHandler
将在文本属性更新时被调用,并允许我们更改与Textfield
相关的状态值。onCommitHandler
,当我们完成对TextField
的编辑后,将调用此名称
deleteHandler
,当我们执行他的删除操作时,将调用它。上面的代码显示了如何使用它们。您最感兴趣的部分是override func deleteBackward()
,通过覆盖此部分,我们可以在按下删除按钮并对其执行操作时挂入。根据使用情况,您可能希望在调用deleteHandler
之前先调用super
。
下一步,我们需要创建UIViewRepresentable
。
struct MyTextField: UIViewRepresentable {
private let tmpView = WrappableTextField()
//var exposed to SwiftUI object init
var tag:Int = 0
var placeholder:String?
var changeHandler:((String)->Void)?
var onCommitHandler:(()->Void)?
var deleteHandler: (()->Void)?
func makeUIView(context: UIViewRepresentableContext<MyTextField>) -> WrappableTextField {
tmpView.tag = tag
tmpView.delegate = tmpView
tmpView.placeholder = placeholder
tmpView.onCommitHandler = onCommitHandler
tmpView.textFieldChangedHandler = changeHandler
tmpView.deleteHandler = deleteHandler
return tmpView
}
func updateUIView(_ uiView: WrappableTextField, context: UIViewRepresentableContext<MyTextField>) {
uiView.setContentHuggingPriority(.defaultHigh, for: .vertical)
uiView.setContentHuggingPriority(.defaultLow, for: .horizontal)
}
}
这是我们创建WrappableTextField
的SwiftUI版本的地方。我们创建WrappableTextField
及其属性。在makeUIView
函数中,我们分配这些属性。最后,在updateUIView
中,我们设置了内容拥抱属性,但是您可以选择不这样做,这实际上取决于您的用例。
最后,我们可以创建一个小的工作示例。
struct ContentView: View {
@State var text = ""
var body: some View {
MyTextField(tag: 0, placeholder: "Enter your name here", changeHandler: { text in
// update the state's value of text
self.text = text
}, onCommitHandler: {
// do something when the editing finishes
print("Editing ended")
}, deleteHandler: {
// do something here when you press delete
print("Delete pressed")
})
}
}