我想通过继承默认的UITextView来编写自定义文本视图。我的实现使用原始组件的委托中的一些方法:

class CustomTextView: UITextView {
    fileprivate func applyStyles() {
        self.layer.cornerRadius = 5
        self.layer.borderColor = .black
        self.layer.borderWidth = 5
        self.clipsToBounds = true
    }

    override func awakeFromNib() {
        super.awakeFromNib()
        applyStyles()
        delegate = self
    }
}

extension CustomTextView: UITextViewDelegate {
    func textViewDidBeginEditing(_ textView: UITextView) {
        print("aaaa")
    }

    func textViewDidEndEditing(_ textView: UITextView) {
        print("bbbb")
    }
}

现在我想在任何地方都使用这个文本视图,而不是标准视图,但是在当前的实现中,我失去了在不丢失自己的委托函数的情况下为组件设置另一个委托的能力。
我是说,如果我要在其他类中创建一个组件,比如:
let customView = CustomTextView()
customView.delegate = self

将不调用CustomTextView中的textViewDidBeginEditing和textViewDidEndEditing函数。我怎样才能绕过这个限制?谢谢。

最佳答案

诀窍是重写delegate属性,以便您可以捕获分配的任何值,然后在代码完成后调用该委托。为此,您的子类需要实现所有UITextViewDelegate函数,以便将调用传递给“real”委托:

class CustomTextView: UITextView {

    private weak var externalDelegate: UITextViewDelegate?

    override var delegate: UITextViewDelegate? {
        set {
            self.externalDelegate = newValue
        }

        get {
            return self.externalDelegate
        }
    }

    fileprivate func applyStyles() {
        self.layer.cornerRadius = 5
        self.layer.borderColor = UIColor.black.cgColor
        self.layer.borderWidth = 5
        self.clipsToBounds = true
    }

    override init(frame: CGRect, textContainer: NSTextContainer?) {
        super.init(frame: frame, textContainer: textContainer)
        super.delegate = self
    }

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

extension CustomTextView: UITextViewDelegate {
    func textViewDidBeginEditing(_ textView: UITextView) {
        print("aaaa")
        self.externalDelegate?.textViewDidBeginEditing?(textView)
    }

    func textViewDidEndEditing(_ textView: UITextView) {
        print("bbbb")
        self.externalDelegate?.textViewDidEndEditing?(textView)
    }

    func textViewShouldBeginEditing(_ textView: UITextView) -> Bool {
        return self.externalDelegate?.textViewShouldEndEditing?(textView) ?? true
    }

    func textViewShouldEndEditing(_ textView: UITextView) -> Bool {
        return self.externalDelegate?.textViewShouldEndEditing?(textView) ?? true
    }

    func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
        return (self.externalDelegate?.textView?(textView, shouldChangeTextIn: range, replacementText: text)) ?? true
    }

    func textViewDidChange(_ textView: UITextView) {
        self.externalDelegate?.textViewDidChange?(textView)
    }

    func textViewDidChangeSelection(_ textView: UITextView) {
            self.externalDelegate?.textViewDidChangeSelection?(textView)
    }

    func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {
        return self.externalDelegate?.textView?(textView, shouldInteractWith: URL, in: characterRange, interaction: interaction) ?? true
    }

    func textView(_ textView: UITextView, shouldInteractWith textAttachment: NSTextAttachment, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {
        return self.externalDelegate?.textView?(textView, shouldInteractWith: textAttachment, in: characterRange, interaction: interaction) ?? true
    }

}

关于ios - Swift-带有委托(delegate)的自定义默认组件,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/52901542/

10-17 00:50