【问题标题】:How can a custom UITextView support 2 delegates - Both internal delegate and external delegate?自定义 UITextView 如何支持 2 个委托 - 内部委托和外部委托?
【发布时间】:2021-08-10 14:04:56
【问题描述】:

我有一个自定义的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

谢谢。

【问题讨论】:

  • 嗯。也许您可以保留内部委托并在方法内部调用回调。然后,当您需要使用外部委托时,您可以从 callbak 访问它。
  • 您需要一个外部委托属性,而您的内部委托必须将调用转发给它。

标签: ios swift uitextview


【解决方案1】:

您可以添加自定义的其他委托属性并使用内部委托将调用转发给它

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
}

【讨论】:

  • 另外,他需要将其他委托设置为VC。 customTextView.other = self
  • 哈哈哈:D至少你改变了它
  • 谢谢。我猜other 应该很弱吧?
【解决方案2】:
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")
        }
    }
}

【讨论】:

  • 这不会涵盖其他委托方法的不同用法,因为callback 对于任何其他添加都是通用的
  • 你是对的。但我只是想展示一种不同的方法。另外,我不知道为什么,但有 2 个代表对我来说似乎不正确。
猜你喜欢
  • 2021-08-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-03
  • 2021-03-23
  • 2011-01-12
  • 2012-04-01
相关资源
最近更新 更多