Como você adiciona inicializadores personalizados a UIViewController
subclasses em Swift?
Eu criei uma subclasse de UIViewController
que se parece com isto:
class MyViewController : UIViewController
{
init(leftVC:UIViewController, rightVC:UIViewController, gap:Int)
{
self.leftVC = leftVC;
self.rightVC = rightVC;
self.gap = gap;
super.init();
setupScrollView();
setupViewControllers();
}
}
Quando o executo, recebo um erro fatal:
erro fatal: uso de inicializador não implementado 'init (nibName: bundle :)' para a classe 'MyApp.MyViewController'
Eu li em outro lugar que, ao adicionar um inicializador personalizado, é necessário também sobrescrever, init(coder aDecoder:NSCoder)
então vamos sobrescrever isso init
e ver o que acontece:
override init(coder aDecoder: NSCoder)
{
super.init(coder: aDecoder);
}
Se eu adicionar isso, o Xcode reclamará disso self.leftVC is not initialized at super.init call
. Então acho que essa também não pode ser a solução. Então, eu me pergunto como posso adicionar inicializadores personalizados corretamente a uma ViewController
subclasse em Swift (já que em Objective-C isso parece não ser um problema)?
fonte
MyViewController
?Respostas:
Resolvi-o! Deve-se chamar o inicializador designado que neste caso é o init com nibName, obviamente ...
init(leftVC:UIViewController, rightVC:UIViewController, gap:Int) { self.leftVC = leftVC self.rightVC = rightVC self.gap = gap super.init(nibName: nil, bundle: nil) setupScrollView() setupViewControllers() }
fonte
Para um UIViewController mais genérico, você pode usá-lo a partir do Swift 2.0
init() { super.init(nibName: nil, bundle: nil) }
fonte
Não tenho certeza se você conseguiu resolver isso totalmente ... mas dependendo de como você deseja que a interface de sua classe pareça e se você realmente precisa ou não da funcionalidade do codificador, você também pode usar o seguinte:
convenience required init(coder aDecoder: NSCoder) { //set some defaults for leftVC, rightVC, and gap self.init(leftVC, rightVC, gap) }
Como
init:leftVC:rightVC:gap
é um inicializador designado, você pode cumprir o requisito de implementaçãoinit:coder
tornando-o um inicializador de conveniência que chama seu inicializador designado.Isso poderia ser melhor do que
override init(coder aDecoder: NSCoder) { super.init(coder: aDecoder); }
porque se você precisar inicializar algumas propriedades, será necessário reescrevê-las.
fonte
Swift 5
Se você quiser escrever um inicializador personalizado para o
UIViewController
qual é inicializado comstoryBoard.instantiateViewController(withIdentifier: "ViewControllerIdentifier")
Você pode escrever o inicializador personalizado apenas para
Optional
propriedades.class MyFooClass: UIViewController { var foo: Foo? init(with foo: Foo) { self.foo = foo super.init(nibName: nil, bundle: nil) } public required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) self.foo = nil } }
fonte