SwiftUI UITextView 协调器不起作用

Posted

技术标签:

【中文标题】SwiftUI UITextView 协调器不起作用【英文标题】:SwiftUI UITextView Coordinator not working 【发布时间】:2019-08-21 18:05:42 【问题描述】:

我已将UITextView 包装在UIViewRepresentable 中,并将Coordinator 包含为UITextViewDelegate,但未调用事件。我做错了什么?


struct TextView : UIViewRepresentable 
    typealias UIViewType = UITextView

    var placeholder : String

    @Binding var text: String

    func makeCoordinator() -> Coordinator 
        Coordinator(self)
    

    func makeUIView(context: UIViewRepresentableContext<TextView>) -> UITextView 
        let textView = UITextView()
        let placeholderLabel = UILabel()        
        textView.font = UIFont(name: "Helvetica", size: 16)
        placeholderLabel.restorationIdentifier = "Placeholder"
        placeholderLabel.text = self.placeholder
        placeholderLabel.font = UIFont.italicSystemFont(ofSize: (textView.font?.pointSize)!)
        placeholderLabel.sizeToFit()
        textView.addSubview(placeholderLabel)
        placeholderLabel.frame.origin = CGPoint(x: 25, y: (textView.font?.pointSize)! / 2 + 12)
        placeholderLabel.textColor = UIColor.lightGray
        placeholderLabel.isHidden = !textView.text.isEmpty

        return textView
    

    func updateUIView(_ uiView: UITextView, context: UIViewRepresentableContext<TextView>) 
        uiView.text = self.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 
            print("Not working")
            return true
        

        func textViewDidChange(_ textView: UITextView) 
            print("Not working")
        


    




【问题讨论】:

有点离题,但是当我开始输入 uitextview 时 placehiolderlabel 不会消失? 【参考方案1】:

这是 Xcode 11.0 beta 6 中的一个工作示例:

import SwiftUI

struct ContentView: View 
     @State var text = ""

       var body: some View 
        VStack 
            Text("text is: \(text)")
            TextView(
                text: $text
            )
                .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
        

       


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: 15)
        myTextView.isScrollEnabled = true
        myTextView.isEditable = true
        myTextView.isUserInteractionEnabled = true
        myTextView.backgroundColor = UIColor(white: 0.0, alpha: 0.05)

        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 
            return true
        

        func textViewDidChange(_ textView: UITextView) 
            print("text now: \(String(describing: textView.text!))")
            self.parent.text = textView.text
        
    


struct ContentView_Previews: PreviewProvider 
    static var previews: some View 
        ContentView()
    

【讨论】:

我刚刚完成了自己的 UITextView 包装,但我没有在 Coordinator 中包含 textView 方法。默认行为似乎是允许更改,所以我想知道您为什么包含它。 谢谢。它也可以在 Mac OS 上运行而无需更改。【参考方案2】:

您必须将textView.delegate = context.coordinator 添加到makeUIView 以注册协调器以接收来自UITextView 的更新。

【讨论】:

谢谢,我错过了...多么明显-.- 我第一次遇到了同样的问题 :-) 在我看来这是设计失败的原因,因为 Coordinator 和 UIViewRepresentable 知道这两种类型,并且函数 makeUIView 返回实际对象,所以为什么不按设计附加它? 希望没有误会!附加到一个委托属性UIViewRepresentableCoordinator UIViewRepresentable 一无所知,它不知道用户是否想要它? :-)。好吧,也许可以通过大量的反思来弄清楚,但可能成本太高太神奇了。 您可能是对的,但 makeCoordinator 不会返回 Coordinator 吗?那么为什么不把它包在幕后呢? :) 是的,太多的魔法不好:P

以上是关于SwiftUI UITextView 协调器不起作用的主要内容,如果未能解决你的问题,请参考以下文章

UITextView 的 SwiftUI Wrapper 未更新 ObservedObject

在 SwiftUI 中为 UITextView 设置初始视图偏移量

作为 UITextView inputAccessoryView 的 SwiftUI 视图具有不正确的框架

UITextView 在 SwiftUI 中可表示不尊重 ScrollView 中的宽度界限

SwiftUI 将数据从协调器中获取到内容视图中

使用dwr后,javaweb设置的session超时失效,web.xml和tomcat设置都不起作