web-dev-qa-db-fra.com

Ignorer la méthode init d'UIView dans swift

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")
    }

}

J'ai une classe où je veux que l'utilisateur initialise une vue personnalisée, soit en donnant des propriétés comme:

let myView = CustomLoadingView(initialize properties here)

Si l'utilisateur ne souhaite pas initialiser ses propres propriétés, je souhaite initialiser CustomLoadingView à l'aide des propriétés par défaut ...

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

Cependant, avec cela, je reçois cette erreur:

Doit appeler un intializer désigné de la super-classe UIView

9
user4790024

Dans init(subviewColor: UIColor, subViewMessage: String), vous n’appelez pas l’initialiseur désigné (comme le souligne gentiment le compilateur).

Si vous ne savez pas ce que sont les initialiseurs désignés, ce sont des initialiseurs que doit être appelés par la sous-classe à un moment donné. De la docs:

Les initialiseurs désignés sont les initialiseurs principaux d'une classe. Un initialiseur désigné initialise complètement toutes les propriétés introduites par cette classe et appelle un initialiseur de superclasse approprié pour poursuivre le processus d'initialisation dans la chaîne de superclasse.

Dans ce cas, l'initialiseur désigné pour UIView est init(frame: CGRect), ce qui signifie qu'à un moment donné votre nouvel initialiseur init(subviewColor: UIColor, subViewMessage: String doit appeler super.init(frame:).

Pour résoudre ce problème, apportez les modifications suivantes:

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

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

}

OU vous pouvez appeler votre autre initialiseur dans votre classe qui finit par appeler l'initialiseur désigné.

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

}

Pour ce qui est de la méthode pratique avec CustomLoadingView(), vous devez ajouter un autre initialiseur pour cela. Ajoutez ce code à votre vue personnalisée:

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

Si vous souhaitez en savoir plus sur les initialiseurs désignés et pratiques, consultez-les ici et ici .

29
tktsubota

Essaye ça:

class CustomView: UIView {

    var subViewColor:UIColor
    var subViewMessage:String

    init(subViewColor:UIColor,subViewMessage:String){

        self.subViewColor = subViewColor
        self.subViewMessage = subViewMessage

        let frame = self.frame
        //Or you can use custom frame. 

        super.init(frame: frame)

    }

    required init(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}
2
TechBee

En revanche, il appelait un xib qui n'existe pas à partir d'un initialiseur de vue personnalisé dans Bundle.main.loadNibNamed("XibNameThatDoesntExist", owner: self, options: nil) `

0
Michal Shatz

Vous devez appeler l'un des initialiseurs désignés par UIView à un moment donné de votre initialiseur personnalisé, par exemple: super.init(frame: frameX). Votre appel de super.init() ne satisfait pas à cette exigence.

0
sakurasunris3