将状态变量传递到自定义文本字段的正确方法是什么?我希望避免其他方法/观察结果。这不应该起作用吗?
我在示例项目中重新创建了下面的问题。
import SwiftUI
struct ParentView: View {
@State var text: String = "initial"
var body: some View {
VStack {
ChildView(text: $text)
Text(self.text)
}
}
}
struct ChildView: View {
@Binding var text: String
var body: some View {
MyTextField(text: $text).frame(width: 300, height: 40, alignment: .center)
}
}
struct MyTextField: UIViewRepresentable {
@Binding var text: String
func makeUIView(context: Context) -> UITextField {
let view = UITextField()
view.borderStyle = UITextField.BorderStyle.roundedRect
return view
}
func updateUIView(_ uiView: UITextField, context: Context) {
uiView.text = text
}
}
Run Code Online (Sandbox Code Playgroud)
Md.*_*lah 15
创建一个@Binding
你喜欢的属性CustomTextField
:
struct CustomTextField: UIViewRepresentable {
@Binding var text: String
}
Run Code Online (Sandbox Code Playgroud)
初始化你的@Binding
财产,init()
如:
init(text: Binding<String>) {
self._text = text
}
Run Code Online (Sandbox Code Playgroud)
将text
属性传递给UITextField
like:
func makeUIView(context: Context) -> UITextField {
// Customise the TextField as you wish
textField.text = text
return textField
}
Run Code Online (Sandbox Code Playgroud)
更新text
如下UITextField
:
func updateUIView(_ uiView: UITextField, context: Context) {
uiView.text = self.text
}
Run Code Online (Sandbox Code Playgroud)
@Binding
使用用户输入的文本更新属性,例如:
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if let value = textField.text as NSString? {
let proposedValue = value.replacingCharacters(in: range, with: string)
parent.text = proposedValue as String // Here is updating
}
return true
}
Run Code Online (Sandbox Code Playgroud)
你的ContentView
应该看起来像:
struct ContentView: View {
@State var text: String = ""
var body: some View {
CustomTextField(text: $text)
}
}
Run Code Online (Sandbox Code Playgroud)
好吧,现在如果您想要完整的代码,CustomTextField
请参阅此答案。
小智 1
看起来绑定文本 ( @Binding var text: String
) 不会改变,而 TextField 的文本即使在 之后发生变化uiView.text = text
,因此您需要通过使用闭包来获取包含绑定文本、TextField 对象和代码的上下文来手动更新绑定文本声明值均衡,并使用Delegate自动调用闭包。但是,TextField 的 Delegate(UITextFieldDelegate 类)没有有效的方法来正确反映文本的更改(func textField 总是在更改之后调用),因此如果使用 Delegate ( class TextViewDelegate),因为它的Delegate有textViewDidChange方法,当改变TextView的文本时肯定会调用这个方法。TextField 或 TextView 的 addTarget 方法将不起作用,因为 Obj-C 函数(闭包)无法在 swift 结构中使用。\n我尝试了以下代码:\n(测试环境:Xcode 11.4.1,Swift 5.2.2\xef \xbc\x89
//Add new:\nvar bindingUpdate:()->Void={} //the definition the closure\n\n//Add new:\nclass TextViewDelegate:UIViewController,UITextViewDelegate{\n func textViewDidChange(_ textView: UITextView) {\n bindingUpdate() //call the closure while text changed\n }\n}\n\n//Modify:\nstruct MyTextView: UIViewRepresentable {\n @Binding var text: String\n var delegate=TextViewDelegate()\n func makeUIView(context: Context) -> UITextView {\n let view = UITextView()\n view.font=UIFont(name: "Helvetica", size: 18)\n view.layer.borderWidth = 2;\n view.layer.cornerRadius = 16;\n view.delegate=delegate\n bindingUpdate={ //the closure\n self.text=view.text\n //add other lines here if you want make other effects while text changed\n }\n return view\n }\n func updateUIView(_ uiView: UITextView, context: Context) {\n uiView.text = text\n }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n我不确定语法是否合适\n但效果很好
\n\n更新\xef\xbc\x9a
\n\n如果您仍然想使用 TextField,这是一个更好的方法:您可以使用 Coordinator 来更新绑定文本。
\n\nstruct MyTextField: UIViewRepresentable {\n @Binding var text: String\n func makeUIView(context: Context) -> UITextField {\n let view = UITextField()\n view.borderStyle = .roundedRect\n view.addTarget(\n context.coordinator,\n action: #selector(Coordinator.updateText(sender:)),\n for: .editingChanged\n )\n return view\n }\n func updateUIView(_ uiView: UITextField, context: Context) {\n uiView.text = text\n }\n func makeCoordinator() -> Coordinator {\n Coordinator(self)\n }\n class Coordinator: NSObject{\n var myView: MyTextField\n\n init(_ view: MyTextField){\n self.myView=view\n }\n @objc func updateText(sender: UITextField){\n myView.text=sender.text!\n }\n }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n这是适当的语法,它也有效,尽管它不能与 TextView 一起使用:它没有 addTarget 方法。
\n 归档时间: |
|
查看次数: |
6970 次 |
最近记录: |