Search code examples
swiftinitializationdesignated-initializerconvenience-methods

Initialize subclass of NSTextView without providing NSTextContainer


I have a subclass of NSTextView, and in my initializer of this subclass I would like to call:

super.init(frame: NSMakeRect(...))

which is what I always do when initializing an NSTextView programmatically. I simply write:

let textView = NSTextView(frame: NSMakeRect(0,0,10,10))

However, when I do this in my subclass (super.init(frame: (...))), the compiler throws an error. It won't let me use init(frame:) because init(frame:) is a convenience initializer of NSTextView, and I must call "a designated initializer of the superclass."

After checking the documentation, I found out that the designated initializer of NSTextView is init(frame: textContainer:) but I don't want to deal with NSTextContainers. Why is it that I must call a designated initializer from a subclass of an object, but I can call a convenience initializer if the object is not being subclassed? Whenever I usually initialize an NSTextView I don't have to provide an NSTextContainer, but when I initialize an NSTextView as the superclass of a subclass, I do. Why is this?

Also, is there any way of initializing an NSTextView with a sort of "default" text container? Regardless of designated initializers, all I want to do here is to create an NSTextView without worrying about NSTextContainers.


Solution

  • I found a work a round for this. It's not pretty, but it gets the job done. Basically I'm just creating an instance of NSTextView inside of my subclass initializer using init(frame:) and then applying the resulting textContainer to super:

    class Header: NSTextView {
    
        // methods and properties...
    
        init(frame theFrame: NSRect) {
            // using desired convenience initializer
            let test = NSTextView(frame: theFrame) 
    
            // using designated initializer, as required by the compiler
            super.init(frame: test.frame, textContainer: test.textContainer) 
        }
    
    }