web-dev-qa-db-fra.com

Pourquoi ne puis-je pas appeler le super.init () par défaut sur UIViewController dans Swift?

Je n'utilise pas un UIViewController d'un storyboard et je veux avoir une fonction personnalisée init dans laquelle je passe dans un NSManagedObjectID d'un objet. Je veux juste appeler super.init() comme dans Objective-C. Comme ça:

init(objectId: NSManagedObjectID) {
    super.init()
}

Mais j'obtiens l'erreur suivante du compilateur:

Doit appeler un initialiseur désigné de la superclasse UIViewController

Puis-je simplement ne plus le faire?

67
SirRupertIII

L'initialisateur désigné pour UIViewController est initWithNibName:bundle:. Vous devriez appeler cela à la place.

Voir http://www.bignerdranch.com/blog/real-iphone-crap-2-initwithnibnamebundle-is-the-designated-initializer-of-uiviewcontroller/

Si vous n'avez pas de nib, transmettez nil pour nibName (le bundle est également facultatif). Ensuite, vous pouvez construire une vue personnalisée dans loadView ou en ajoutant des sous-vues à self.view dans viewDidLoad, comme auparavant.

100
occulus

Une autre solution intéressante consiste à déclarer votre nouvel initialiseur en tant qu’initialiseur convenience comme suit:

convenience init( objectId : NSManagedObjectID ) {
    self.init()

    // ... store or user your objectId
}

Si vous ne déclarez aucun initialiseur désigné dans votre sous-classe, ils sont automatiquement hérités et vous pouvez utiliser self.init() au sein de votre initialiseur de confort.

Dans le cas de UIViewController, la méthode init par défaut appellera init(nibName nibNameOrNil: String!, bundle nibBundleOrNil: NSBundle!) avec nil pour les deux arguments (cliquez sur UIViewController pour obtenir ces informations).

TL; TR: Si vous préférez travailler par programme avec UIViewControllers, voici un exemple de travail complet qui ajoute un nouvel initialiseur avec un argument personnalisé:

class MyCustomViewController: UIViewController {
    var myString: String = ""

    convenience init( myString: String ) {
        self.init()

        self.myString = myString
    }
}
38
Klaas

Pour améliorer la réponse occulus:

init() {
     super.init(nibName: nil, bundle: nil)
}
8
Vyacheslav

Mise à jour: ajouter le lien

https://developer.Apple.com/documentation/uikit/uiviewcontroller/1621359-init

Selon la documentation pour iOS, l'initialiseur désigné pour UIViewController est initWithNibName: bundle:.

Si vous sous-classez UIViewController, vous devez appeler la super-implémentation de cette méthode, même si vous n'utilisez pas de NIB.

Vous pouvez le faire comme suit:

init(objectId : NSManagedObjectID) {

    super.init(nibName: (xib's name or nil'), bundle: nil)

   // other code...
}

ou

Déclarez un nouvel initialiseur en tant qu'initialiseur de commodité:

 convenience init( objectId : NSManagedObjectID ) {

    self.init()

     // other code...

}

8
NcNc