web-dev-qa-db-fra.com

Swift: initialiseurs ViewController personnalisés

Comment ajouter des initialiseurs personnalisés aux sous-classes UIViewController de Swift?

J'ai créé une sous-classe de UIViewController qui ressemble à ceci:

class MyViewController : UIViewController
{
    init(leftVC:UIViewController, rightVC:UIViewController, gap:Int)
    {
        self.leftVC = leftVC;
        self.rightVC = rightVC;
        self.gap = gap;

        super.init();

        setupScrollView();
        setupViewControllers();
    }
}

Quand je le lance, j'obtiens une erreur fatale:

erreur fatale: utilisation de l'initialiseur non implémenté 'init (nibName: bundle :)' pour la classe 'MyApp.MyViewController'

J'ai lu ailleurs que, lors de l'ajout d'un initialiseur personnalisé, il faut également remplacer init(coder aDecoder:NSCoder), donc écrasons-le init et voyons ce qui se passe:

override init(coder aDecoder: NSCoder)
{
    super.init(coder: aDecoder);
}

Si j'ajoute cela, Xcode se plaint que self.leftVC is not initialized at super.init call. Donc, je suppose que cela ne peut pas être la solution non plus. Je me demande donc comment ajouter correctement des initialiseurs personnalisés à une sous-classe ViewController dans Swift (car cela ne semble pas poser de problème en Objective-C))?

77
BadmintonCat

Résolu! Il faut appeler l'initialiseur désigné qui, dans ce cas, est init avec nibName, évidemment ...

init(leftVC:UIViewController, rightVC:UIViewController, gap:Int)
{
    self.leftVC = leftVC
    self.rightVC = rightVC
    self.gap = gap

    super.init(nibName: nil, bundle: nil)

    setupScrollView()
    setupViewControllers()
}
107
BadmintonCat

Vous ne savez pas si vous êtes parvenu à résoudre complètement ce problème ... mais en fonction de l'apparence que vous souhaitez donner à l'interface de votre classe et de la nécessité ou non de la fonctionnalité du codeur, vous pouvez également utiliser les éléments suivants:

convenience required init(coder aDecoder: NSCoder)
{
    //set some defaults for leftVC, rightVC, and gap
    self.init(leftVC, rightVC, gap)
}

Puisque init:leftVC:rightVC:gap est un initialiseur désigné, vous pouvez remplir la condition d'implémentation de init:coder en en faisant un initialiseur de commodité qui appelle votre initialiseur désigné.

Cela pourrait être mieux que

override init(coder aDecoder: NSCoder)
{
    super.init(coder: aDecoder);
}

parce que si vous avez besoin d’initialiser certaines propriétés, vous devrez alors les réécrire.

11
wlingke

Pour un UIViewController plus générique, vous pouvez l’utiliser à partir de Swift 2.0

init() {
    super.init(nibName: nil, bundle: nil)
}
11
Tr0yJ