I'm trying to have all my TextView instances use this same delegate function from UITextPasteDelegate without copying the delegate function into each VC.
Xcode 10.3 compiler doesn't throw an error when I do this:
extension UITextView : UITextPasteDelegate {
private func textPasteConfigurationSupporting(_ textPasteConfigurationSupporting: UITextPasteConfigurationSupporting, shouldAnimatePasteOf attributedString: NSAttributedString, to textRange: UITextRange) -> Bool {
return false
}
}
However the problem I run into is when I try to set this delegate in my VC. The code looks something like this:
class viewController : UIViewController{
@IBOutlet weak var textView: UITextView!
override func viewDidLoad() {
super.viewDidLoad()
textView.pasteDelegate = self
}
}
It breaks on the line textView.pasteDelegate = self and I understand that it breaks here because the viewController class is not implementing UITextPasteDelegate. But my question is whether it is possible to assign textView.pasteDelegate = ? to something. I've tried textView.pasteDelegate = UITextView.Type but that also fails.
Is there a way to achieve this?
Extensions cannot override methods. This is not supported. Sometimes it may happen to work, but it is undefined behavior.
From Extensions in The Swift Programming Language:
Extensions can add new functionality to a type, but they cannot override existing functionality.
(This is all true, but doesn't actually apply to this question; see more below.)
This is exactly what subclasses are for. In Interface Builder, select your subclass and it'll still wire up as a UITextView. It'll just be configured the way you want. For example:
class NonAnimatingTextView: UITextView {
override init(frame: CGRect, textContainer: NSTextContainer?) {
super.init(frame: frame, textContainer: textContainer)
self.pasteDelegate = self
}
required init?(coder: NSCoder) {
super.init(coder: coder)
}
}
extension NonAnimatingTextView: UITextPasteDelegate {
func textPasteConfigurationSupporting(
_ textPasteConfigurationSupporting: UITextPasteConfigurationSupporting,
shouldAnimatePasteOf attributedString: NSAttributedString,
to textRange: UITextRange) -> Bool { false }
}
For completeness, the exact thing you're trying to do is in fact possible; it's just not the right approach. (In this case it works out that it's not an override, so it's possible.)
First, you marked the method as private when it should be public and ideally @objc
(@objc
may not be required here, but I would add it to be very clear):
extension UITextView : UITextPasteDelegate {
@objc public func textPasteConfigurationSupporting(_ textPasteConfigurationSupporting: UITextPasteConfigurationSupporting, shouldAnimatePasteOf attributedString: NSAttributedString, to textRange: UITextRange) -> Bool {
return false
}
}
And then the UITextView is its own pasteDelegate
:
class ViewController : UIViewController{
@IBOutlet weak var textView: UITextView!
override func viewDidLoad() {
super.viewDidLoad()
textView.pasteDelegate = textView
}
}
But I still recommend the subclass. It's much clearer what you're doing.
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments