首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在子类和UIViewController中使用UITextViewDelegate

在子类和UIViewController中使用UITextViewDelegate
EN

Stack Overflow用户
提问于 2016-03-27 04:22:06
回答 3查看 597关注 0票数 2

我对UITextView进行了子类化,并在像textViewDidChangeSelection这样的子类中实现了一些委托方法,但我还需要在视图控制器中为UITextView委托获取通知。因此,如果我创建了子类的对象并在视图控制器中设置了textview委托,那么委托方法只会在视图控制器中被通知,而不会在子类中被通知。我需要通知两个班级。我使用的语言是swift 2

我尝试在子类委托中继承UITextViewDelegate:

代码语言:javascript
复制
@objc protocol CustomTextViewDelegate:UITextViewDelegate {

    func customTextViewDidChangeSize(chatTextView: CustomTextView)

}

然后在VC中:

代码语言:javascript
复制
let customTV = CustomTextView()
customTV.customTextViewDelegate = self

但是任何文本视图委托方法都不会被调用。

EN

回答 3

Stack Overflow用户

发布于 2020-09-29 20:28:26

问得好。这是一个不太好的答案,因为它需要你重写所有的委托方法,因此在iOS版本中不稳定,以防委托方法随着时间的推移而改变。

在这种方法中,ViewControllerCustomTextField都可以访问委托事件。

代码语言:javascript
复制
class CustomTextView: UITextView {
   override var delegate: UITextViewDelegate? {
      set {
         superDelegate = newValue
      } get {
         return superDelegate
      }
    }

    private weak var superDelegate: UITextViewDelegate?

    init() {
       super.init(frame: .zero, textContainer: nil)
       super.delegate = self
    }

    func textDidChange(text: String?) {
        // do something
    }

}

extension BoundTextView: UITextViewDelegate {
    public func textViewDidChange(_ textView: UITextView) {
        // catch text-change events here
        textDidChange(text: String?) 
        superDelegate?.textViewDidChange?(textView)
    }

    public func textViewDidEndEditing(_ textView: UITextView) {
        superDelegate?.textViewDidEndEditing?(textView)
    }

    public func textViewDidChangeSelection(_ textView: UITextView) {
        superDelegate?.textViewDidChange?(textView)
    }

    public func textViewShouldBeginEditing(_ textView: UITextView) -> Bool {
       return superDelegate?.textViewShouldBeginEditing?(textView) ?? false
    }

    public func textViewDidBeginEditing(_ textView: UITextView) {
        superDelegate?.textViewDidBeginEditing?(textView)
    }

    public func textViewShouldEndEditing(_ textView: UITextView) -> Bool {
       return superDelegate?.textViewShouldEndEditing?(textView) ?? false
    }

    public func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
        return superDelegate?.textView?(textView, shouldChangeTextIn: range, replacementText: text) ?? false
    }

    public func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {
        return superDelegate?.textView?(textView, shouldInteractWith: URL, in: characterRange, interaction: interaction) ?? false
    }

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

我们覆盖delegate并将对它的引用存储在一个单独的变量(称为superDelegate)中。CustomTextField将自身分配给super.delegate并实现UITextView-delegate。我们必须确保每个委托事件都会触发相应的superDelegate事件。

我们的“ViewController”现在可以将自己指定为CustomTextView的委托:

代码语言:javascript
复制
class ViewController: UIViewController {

   ...
   lazy var textField: CustomTextView {
      let textView = CustomTextField()
      textView.delegate = self 
      return textField
   }()
   ...


}

extension ViewController: UITextViewDelegate {

   // implement only the delegate-methods you need

}

现在,ViewControllerCustomTextField都可以访问UITextFieldDelegate

票数 2
EN

Stack Overflow用户

发布于 2016-03-27 05:27:04

不能同时将两个对象委托给UITextView对象。因此,您应该为CustomTextView创建新的协议(CustomTextViewDelegate),并在其中创建委托属性。让你的ViewController确认这个CustomTextViewDelegate并实现它的方法。在CustomTextViewUITextViewDelegate方法实现中,可以调用适当的CustomTextViewDelegate方法。

票数 0
EN

Stack Overflow用户

发布于 2021-05-02 03:11:07

@nayooti的方法很好,但是我必须做一些修复才能正常工作,主要的一个是一些委托方法不会被调用(例如shouldChangeTextIn rangetextViewDidChange )。

我发现可以通过在被覆盖的delegate变量的get访问器上返回super.delegate而不是superDelegate来修复它。

代码语言:javascript
复制
class CustomTextView: UITextView {
    
    override var delegate: UITextViewDelegate? {
        set {
            superDelegate = newValue
        } get {
            return super.delegate
        }
    }
    
    private weak var superDelegate: UITextViewDelegate?
    
    init() {
        super.init(frame: .zero, textContainer: nil)
        super.delegate = self
    }
    
    override public init(frame: CGRect, textContainer: NSTextContainer?) {
        super.init(frame: frame, textContainer: textContainer)
        super.delegate = self
    }
    
    required public init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        super.delegate = self
    }
    
    func textDidChange(text: String?) {
        // Do something
    }
    
}

extension CustomTextView: UITextViewDelegate {
    
    public func textViewDidChange(_ textView: UITextView) {
        // Catch text-change events here
        textDidChange(text: textView.text)
        superDelegate?.textViewDidChange?(textView)
    }
    
    public func textViewDidEndEditing(_ textView: UITextView) {
        superDelegate?.textViewDidEndEditing?(textView)
    }
    
    public func textViewDidChangeSelection(_ textView: UITextView) {
        superDelegate?.textViewDidChange?(textView)
    }
    
    public func textViewShouldBeginEditing(_ textView: UITextView) -> Bool {
        return superDelegate?.textViewShouldBeginEditing?(textView) ?? true
    }
    
    public func textViewDidBeginEditing(_ textView: UITextView) {
        superDelegate?.textViewDidBeginEditing?(textView)
    }
    
    public func textViewShouldEndEditing(_ textView: UITextView) -> Bool {
        return superDelegate?.textViewShouldEndEditing?(textView) ?? true
    }
    
    public func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
        return superDelegate?.textView?(textView, shouldChangeTextIn: range, replacementText: text) ?? true
    }
    
    public func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {
        return superDelegate?.textView?(textView, shouldInteractWith: URL, in: characterRange, interaction: interaction) ?? true
    }
    
    public func textView(_ textView: UITextView, shouldInteractWith textAttachment: NSTextAttachment, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {
        return superDelegate?.textView?(textView, shouldInteractWith: textAttachment, in: characterRange, interaction: interaction) ?? true
    }
    
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36240452

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档