Comment créer un initialiseur personnalisé pour une sous-classe UIViewController dans Swift?

Toutes mes excuses, si cela a déjà été demandé, j’ai beaucoup cherché et beaucoup de réponses proviennent de bêtas Swift antérieures lorsque les choses étaient différentes. Je n’arrive pas à trouver une réponse définitive.

Je veux sous-classe UIViewController et avoir un initialiseur personnalisé pour me permettre de le configurer facilement dans le code. J’ai du mal à faire ça à Swift.

Je veux une fonction init() que je peux utiliser pour passer un NSURL spécifique que je vais ensuite utiliser avec le contrôleur de vue. Dans mon esprit, cela ressemble à init(withImageURL: NSURL) . Si j’ajoute cette fonction, il me demande alors d’append la fonction init(coder: NSCoder) .

Je crois que c’est parce qu’il est marqué dans la superclasse avec le mot-clé required ? Donc, je dois le faire dans la sous-classe? Je l’ajoute:

 required init(coder aDecoder: NSCoder) { super.init(coder: aDecoder) } 

Maintenant quoi? Mon initialisateur spécial est-il considéré comme convenience ? Un désigné? Est-ce que j’appelle un super initialiseur? Un initialiseur de la même classe?

Comment append mon initialiseur spécial à une sous-classe UIViewController ?

 class ViewController: UIViewController { var imageURL: NSURL? // this is a convenient way to create this view controller without a imageURL convenience init() { self.init(imageURL: nil) } init(imageURL: NSURL?) { self.imageURL = imageURL super.init(nibName: nil, bundle: nil) } // if this view controller is loaded from a storyboard, imageURL will be nil /* Xcode 6 required init(coder aDecoder: NSCoder) { super.init(coder: aDecoder) } */ // Xcode 7 & 8 required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) } } 

Les initialiseurs de commodité sont secondaires, prenant en charge les initialiseurs pour une classe. Vous pouvez définir un initialiseur de commodité pour appeler un initialiseur désigné de la même classe que l’initialiseur de commodité, certains des parameters de l’initialiseur désignés étant définis sur les valeurs par défaut. Vous pouvez également définir un initialiseur de commodité pour créer une instance de cette classe pour un cas d’utilisation ou un type de valeur d’entrée spécifique.

Ils sont documentés ici .

Si vous avez besoin d’une init personnalisée pour un popover par exemple, vous pouvez utiliser l’approche suivante:

Créez une init personnalisée qui utilise super init avec nibName et bundle, puis accède à la propriété view pour forcer le chargement de la hiérarchie de vue.

Ensuite, dans la fonction viewDidLoad, vous pouvez configurer les vues avec les parameters transmis lors de l’initialisation.

 import UIKit struct Player { let name: Ssortingng let age: Int } class VC: UIViewController { @IBOutlet weak var playerName: UILabel! let player: Player init(player: Player) { self.player = player super.init(nibName: "VC", bundle: Bundle.main) if let view = view, view.isHidden {} } override func viewDidLoad() { super.viewDidLoad() configure() } func configure() { playerName.text = player.name + "\(player.age)" } } func showPlayerVC() { let foo = Player(name: "bar", age: 666) let vc = VC(player: foo) present(vc, animated: true, completion: nil) }