自定义 UITextView 如何支持 2 个委托 - 内部委托和外部委托?

How can a custom UITextView support 2 delegates - Both internal delegate and external delegate?

我有一个自定义 UITextView,它本身包含一个内部私有委托。

import UIKit

class CustomTextView: UITextView {
    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)!
        
        self.delegate = self
    }
}

extension CustomTextView: UITextViewDelegate {
    func textViewDidChange(_ textView: UITextView) {
        print("CustomTextView delegate textViewDidChange (Performing operation like setNeedsDisplay to implement custom drawing)")
    }
}

但是,如果我开始应用这个 CustomTextView,并应用一个外部委托,它将被破坏,因为它的初始内部委托将不会被执行。

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var customTextView: CustomTextView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        customTextView.delegate = self
    }
}

extension ViewController: UITextViewDelegate {
    func textViewDidChange(_ textView: UITextView) {
        print("ViewController delegate textViewDidChange")
    }
}

如果我们执行上面的代码,只有

ViewController delegate textViewDidChange

将被打印出来。

我想知道,有什么好的设计可以确保支持多个代表,以便两者都被打印出来?

CustomTextView delegate textViewDidChange (Performing operation like setNeedsDisplay to implement custom drawing)
ViewController delegate textViewDidChange

谢谢。

您可以添加自定义其他委托 属性 并使用内部委托

将调用转发给它
class CustomTextView: UITextView {
    weak var other:UITextViewDelegate?
    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)! 
        self.delegate = self
    }
}

extension CustomTextView: UITextViewDelegate {
    func textViewDidChange(_ textView: UITextView) {
        print("CustomTextView delegate textViewDidChange (Performing operation like setNeedsDisplay to implement custom drawing)")
        other?.textViewDidChange?(textView)
    }
}

然后

override func viewDidLoad() {
    super.viewDidLoad()
    
    customTextView.other = self
}
class CustomTextView: UITextView {

    var callback: (() -> Void)?

    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)! 
        self.delegate = self
    }
}

extension CustomTextView: UITextViewDelegate {
    func textViewDidChange(_ textView: UITextView) {
        print("CustomTextView delegate textViewDidChange (Performing operation like setNeedsDisplay to implement custom drawing)")
        self.callback?()
    }
}

还有你的ViewController欢迎回电。

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var customTextView: CustomTextView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        customTextView.callback = { 
           print("ViewController delegate textViewDidChange")
        }
    }
}