Override init method of UIView in swift

41,526

In init(subviewColor: UIColor, subViewMessage: String), you aren't calling the designated initializer (as the compiler points out nicely).

If you don't know what designated initializers are, they are initializers that have to be called by the subclass at some point. From the docs:

Designated initializers are the primary initializers for a class. A designated initializer fully initializes all properties introduced by that class and calls an appropriate superclass initializer to continue the initialization process up the superclass chain.

In this case, the designated initializer for UIView is init(frame: CGRect), meaning at some point, your new initializer init(subviewColor: UIColor, subViewMessage: String must call super.init(frame:).

In order to fix this, make the following changes:

init(frame: CGRect, subViewColor: UIColor, subViewMessage: String){

    self.subViewColor = subViewColor
    self.subViewMessage = subViewMessage
    super.init(frame: frame)

}

OR you can call your other initializer in your class which ends up calling the designated initializer.

override init(frame: CGRect) {
    super.init(frame: frame) // calls designated initializer
}

convenience init(frame: CGRect, subViewColor: UIColor, subViewMessage: String){

    self.subViewColor = subViewColor
    self.subViewMessage = subViewMessage
    self.init(frame: frame) // calls the initializer above

}

As for the convenience method with simply CustomLoadingView(), you have to add another initializer for that. Add this code to your custom view:

convenience init() {
    self.init(frame: DEFAULT_FRAME, subViewColor: DEFAULT_COLOR, subViewMessage: DEFAULT_MESSAGE)
}

If you want to learn more about designated and convenience initializers, read about them here and here.

Share:
41,526
tktsubota
Author by

tktsubota

Updated on October 26, 2020

Comments

  • tktsubota
    tktsubota over 3 years
    class CustomView: UIView {
    
        var subViewColor:UIColor
        var subViewMessage:String
    
        override init(frame:CGRect) {
            super.init(frame:frame)
        }
    
        init(subViewColor:UIColor,subViewMessage:String){
    
            self.subViewColor = subViewColor
            self.subViewMessage = subViewMessage
            super.init()
    
        }
    
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
    
    }
    

    I have a class where I want the user to initialize a custom view either by giving properties like:

    let myView = CustomLoadingView(initialize properties here)
    

    If the user does not want to initialize their own properties, I want to initialize CustomLoadingView using default properties...

    let myView = CustomLoadingView() // this should initialize using default value
    

    However, with this, I am getting this error:

    Must call a designated intializer of the superclass UIView

  • Joseph
    Joseph over 7 years
    This only works for me if I call self.init(frame: frame) as the first thing in the convenience init method
  • invisible squirrel
    invisible squirrel over 6 years
    Produces a compiler error: 'self' used before super.init call. See this answer.
  • Tarek hemdan
    Tarek hemdan almost 6 years
    you can't use self before calling the super function