Isso é muito semelhante às outras respostas, mas com alguma explicação. A resposta aceita é enganosa porque sua propriedade é opcional e não expõe o fato de que você init?(coder: NSCoder)
DEVE inicializar cada propriedade e a única solução para isso é ter um fatalError()
. No final das contas, você poderia escapar tornando suas propriedades opcionais, mas isso não responde verdadeiramente à pergunta do OP.
// Think more of a OnlyNibOrProgrammatic_NOTStoryboardViewController
class ViewController: UIViewController {
let name: String
override func viewDidLoad() {
super.viewDidLoad()
}
// I don't have a nib. It's all through my code.
init(name: String) {
self.name = name
super.init(nibName: nil, bundle: nil)
}
// I have a nib. I'd like to use my nib and also initialze the `name` property
init(name: String, nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle? ) {
self.name = name
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
}
// when you do storyboard.instantiateViewController(withIdentifier: "ViewController")
// The SYSTEM will never call this!
// it wants to call the required initializer!
init?(name: String, coder aDecoder: NSCoder) {
self.name = "name"
super.init(coder: aDecoder)
}
// when you do storyboard.instantiateViewController(withIdentifier: "ViewController")
// The SYSTEM WILL call this!
// because this is its required initializer!
// but what are you going to do for your `name` property?!
// are you just going to do `self.name = "default Name" just to make it compile?!
// Since you can't do anything then it's just best to leave it as `fatalError()`
required init?(coder aDecoder: NSCoder) {
fatalError("I WILL NEVER instantiate through storyboard! It's impossible to initialize super.init?(coder aDecoder: NSCoder) with any other parameter")
}
}
Você basicamente tem que ABANDONAR o carregamento do storyboard. Por quê?
Porque quando você chama um viewController, storyboard.instantiateViewController(withIdentifier: "viewController")
então o UIKit fará seu trabalho e chamará
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
Você nunca pode redirecionar essa chamada para outro método init.
Docs em instantiateViewController(withIdentifier:)
:
Use este método para criar um objeto de controlador de visualização para apresentar programaticamente. Cada vez que você chama este método, ele cria uma nova instância do controlador de visualização usando o init(coder:)
método.
No entanto, para viewController criado programaticamente ou viewControllers criados com nib, você pode redirecionar essa chamada conforme mostrado acima.