Search code examples
iosswiftuitextviewiboutletbecomefirstresponder

Lazily Override IBOutlet Object's Properties


I have a custom UItextView subclass where I override canBecomeFirstResponder():

class MyTextView: UITextView {

    /*
    // Only override drawRect: if you perform custom drawing.
    // An empty implementation adversely affects performance during animation.
    override func drawRect(rect: CGRect) {
        // Drawing code
    }
    */

    override func canBecomeFirstResponder() -> Bool {
        return false
    }

}

I'm doing this to allow the data detected links (phone numbers are URLs) in a UITextView to function without any of the other text in the view to be selectable, but that is unrelated to the question.

canBecomeFirstResponder() is the only property/method I want to override, so subclassing seems like overkill. I use this custom class with a view created with Interface Builder. Is there a way I can lazily override an IBOutlet's of a UIKit object's properties? Something like this:

@IBOutlet weak var contactTextView: UITextView! {
    override func canBecomeFirstResponder: Bool = {
        return false
    }
}

I do not want to use an extension on UITextView because I only want to override canBecomeFirstResponder() for a specific UITextView, not every one used in my project.


Solution

  • If you want to override, you have to subclass. These two concepts are connected. You cannot override without subclassing.

    Your "like this" idea wouldn't work in any language. Basically, you are describing an anonymous subclass which is available in Java, for instance (not in Swift). However, that would have to be used during class instantiation, not when declaring a variable.

    Of course, you could swizzle canBecomeFirstResponder with a method returning false in didSet but that's much more complicated than subclassing.