如何添加 onCommit、isEditing 以及自定义绑定到自定义 textview 的能力?
Posted
技术标签:
【中文标题】如何添加 onCommit、isEditing 以及自定义绑定到自定义 textview 的能力?【英文标题】:How to add onCommit, isEditing, and ability to have a custom binding to a custom textview? 【发布时间】:2020-08-30 18:25:25 【问题描述】:提供以下 UIViewRepresentable isEditing 和 onCommit 属性的最佳方法是什么?我希望它在 SwiftUI 中调用 TextFields 时具有相同的确切功能(您可以在其中添加代码以说明按下返回键 [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
)
【问题讨论】:
【参考方案1】: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")
)
可以应用类似的变化检测方法
关于编辑
你可以使用类似我上面解释的onCommit
的方法或者如果你使用的是SwiftUI 2.0,你可以用.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
值:
您需要通过在coordinator
中实现此功能来更新UIKit
端的text
:
func textViewDidChange(_ textView: UITextView)
parent.text = textView.text
然后实际绑定的变量会根据 textField 的文本更改事件进行更新。
? 弹跳
通过此方法,您还可以将配置步骤转发到SwiftUI
端。所以重构后的完整工作代码如下:
struct ContentView: View
@State var text: String = ""
var body: some View
TextView(text: $text) // Configuring the text field
$0.font = UIFont(name: "HelveticaNeue", size: 16)
$0.isScrollEnabled = true
$0.isEditable = true
$0.isUserInteractionEnabled = true
$0.backgroundColor = UIColor(white: 0.0, alpha: 0.00)
$0.textColor = UIColor.black
onCommit: // Detecting the commit
print("Committed with text: " + text)
.onChange(of: text) value in // The native way to detect changes of a State
print("text now: " + text)
struct TextView: UIViewRepresentable
@Binding var text: String
var configurate: (UITextView) -> ()
var onCommit: ()->()
func makeCoordinator() -> Coordinator
Coordinator(self)
func makeUIView(context: Context) -> UITextView
let myTextView = UITextView()
configurate(myTextView) // Forwarding the configuring step
myTextView.delegate = context.coordinator
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()
parent.onCommit() // Execute the passed `onCommit` method here
return true
func textViewDidChange(_ textView: UITextView)
parent.text = textView.text // Update the actual variable
【讨论】:
谢谢!很详细的回答 谢谢,这很有帮助以上是关于如何添加 onCommit、isEditing 以及自定义绑定到自定义 textview 的能力?的主要内容,如果未能解决你的问题,请参考以下文章
SwiftUI - 如何在另一个视图中响应 TextField onCommit?
Angular 6 中的剑道网格:isEditing:如何?
以编程方式 ComboBox VirtualizingStackPanel WPF