好问题。这是一个不太好的答案,因为它需要您重写所有委托方法,因此在委托方法随时间变化的情况下跨 iOS 版本并不稳定。
在这种方法中,ViewController 和 CustomTextField 都可以访问委托事件。
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 的委托:
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
}
现在ViewController 和CustomTextField 都可以访问UITextFieldDelegate。