问题描述
赋予下面的UIViewRepresentable isEditing和onCommit属性的最佳方法是什么?我希望它在SwiftUI中对TextField的调用具有相同的确切功能(您可以在其中添加代码,用于按[onCommit]上的回车键或单击[isEditing]上的文本字段时的操作)
struct TextView: UIViewRepresentable {
@Binding var text: String
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
func makeUIView(context: Context) -> UITextView {
let myTextView = UITextView()
myTextView.delegate = context.coordinator
myTextView.font = UIFont(name: "HelveticaNeue",size: 16)
myTextView.isScrollEnabled = true
myTextView.isEditable = true
myTextView.isUserInteractionEnabled = true
myTextView.backgroundColor = UIColor(white: 0.0,alpha: 0.00)
myTextView.textColor = UIColor.black
return myTextView
}
func updateUIView(_ uiView: UITextView,context: Context) {
uiView.text = text
}
class Coordinator : NSObject,UITextViewDelegate {
var parent: TextView
init(_ uiTextView: TextView) {
self.parent = uiTextView
}
func textView(_ textView: UITextView,shouldChangeTextIn range: NSRange,replacementText text: String) -> Bool {
if (text == "\n") {
textView.resignFirstResponder()
}
return true
}
func textViewDidChange(_ textView: UITextView) {
print("text Now: \(String(describing: textView.text!))")
self.parent.text = textView.text
}
}
}
侧面注意:我不确定为什么,但是我传入的绑定变量不会更改实际值。我知道,因为我使用get / set属性设置了自定义绑定,而该设置未打印该值。 (此值应该是传递到textview中的文本)
let binding = Binding<String>(get: {
self.bindingVariableName
},set: {
print("set the value")
self.bindingVariableName = $0
}
)
解决方法
onCommit
您可以将函数作为变量传递,以使它们在正确的位置执行,例如:
struct TextView: UIViewRepresentable {
@Binding var text: String
var onCommit: ()->()
...
}
... {
...
func textView(_ textView: UITextView,shouldChangeTextIn range: NSRange,replacementText text: String) -> Bool {
if (text == "\n") {
textView.resignFirstResponder()
parent.onCommit() // <- execute here
}
return true
}
}
并像这样使用它:
TextView(text: $text,onCommit: {
print("Committed")
})
可以应用类似的检测变化的方法
onEditting
您可以使用类似我上面解释的onCommit
的方法,或者,如果您使用的是 SwiftUI 2.0 ,则可以观察{ {1}}修饰符(如果实际值从.onChange
一侧变化),例如:
SwiftUI
更新实际的struct ContentView: View {
@State var text: String = ""
var body: some View {
TextView(text: $text)
.onChange(of: text) { value in
print("text now: " + text)
}
}
}
值:
您需要通过在@Binding
中实现此功能来更新text
中的{strong> UIKit
:
coordinator
然后,实际绑定变量将根据textField的文本更改事件进行更新。
?Bouns
使用此方法,您还可以将配置步骤转发到func textViewDidChange(_ textView: UITextView) {
parent.text = textView.text
}
侧。因此,重构后的完整工作代码如下:
SwiftUI