que life ios swift uiviewcontroller uikit designated-initializer

ios - life - Cómo escribir los métodos init de un UIViewController en Swift



viewcontroller que es (6)

No puedo agregar el método init a la siguiente clase UIViewController. Necesito escribir algo de código en el método init. ¿Tengo que escribir el método init (codificador)? Incluso cuando agrego los métodos de codificador y decodificador, todavía obtengo errores. También intenté usar el método init sin ningún parámetro, pero tampoco parece funcionar.

class ViewController: UIViewController { var tap: UITapGestureRecognizer? override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) { super.init(nibName: nil, bundle: nil) tap = UITapGestureRecognizer(target: self, action: Selector("handleTap:")) } ... ... }

Si llamo al método super.init () sin parámetros, el error es "Debo llamar a un inicializador designado de la superclase" y si paso el nib y el parámetro del parámetro, entonces el error es "Inicializador inicial requerido (codificador)".

Incluso cuando agrego init (codificador) y init (decodificador) no funciona.


Creo que tienes que añadir

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

o

convenience init() { self.init() }

Tienes que escribir init también. No lo quites

var tap: UITapGestureRecognizer? override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) { super.init(nibName: nil, bundle: nil) }

Espero eso ayude


En su lugar, puede simplemente crear un inicializador de conveniencia, los inicializadores de conveniencia no anulan el init (), sino que lo llaman a hacer las cosas más fáciles.

class ViewController: UIViewController { var tap: UITapGestureRecognizer? convenience init(){ self.init() tap = UITapGestureRecognizer(target: self, action: Selector("handleTap:")) } }


Me encontré con esta pregunta de que pediste largo camino de vuelta. Pero nadie ha proporcionado una respuesta básica a la pregunta. Es básico en Swift que: - La subclase debe inicializar sus variables antes de que se complete la inicialización de la súper clase.

Por lo tanto, como Ankit Goel mencionó el bloqueo: "Debe llamar a un inicializador designado de superclase"

Por lo tanto, el código actualizado sería:

class ViewController: UIViewController { var tap: UITapGestureRecognizer? override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { print("init nibName style") self.tap = nil super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) self.tap = UITapGestureRecognizer(target: self, action: Selector(("handleTap:"))) } required init?(coder aDecoder: NSCoder) { print("init coder style") self.tap = nil super.init(coder: aDecoder) tap = UITapGestureRecognizer(target: self, action: Selector(("handleTap:"))) }}


Solía:

convenience init() { self.init(nibName:nil, bundle:nil) }

Algunas personas sugirieron:

convenience init(){ self.init() }

Pero esto te da un bucle infinito.


Todas estas respuestas son respuestas a medias. Algunas personas están experimentando bucles infinitos en publicaciones relacionadas porque solo están agregando la convenience init() (se llama a sí misma de forma recursiva si no proporciona un método init() distinto para que pueda invocar), mientras que otras personas se niegan a extender la superclase Este formato combina todas las soluciones para satisfacer completamente el problema.

// This allows you to initialise your custom UIViewController without a nib or bundle. convenience init() { self.init(nibName:nil, bundle:nil) } // This extends the superclass. override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) tap = UITapGestureRecognizer(target: self, action: Selector("handleTap:")) } // This is also necessary when extending the superclass. required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") // or see Roman Sausarnes''s answer }

Edición: Además, si desea inicializar las propiedades de clase utilizando parámetros pasados ​​a su método de convenience init() iniciación convenience init() sin quejen de todos los métodos de init() anulados, puede configurar todas esas propiedades como opcionales implícitamente desempaquetadas, que es un patrón utilizado por Apple ellos mismos .


init(nibName:bundle:) anular el init(nibName:bundle:) y proporcionar el init(coder:) requerido init(coder:) e inicializar el tap en ambos:

class ViewController: UIViewController { var tap: UITapGestureRecognizer? override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { print("init nibName style") super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) tap = UITapGestureRecognizer(target: self, action: Selector("handleTap:")) } // note slightly new syntax for 2017 required init?(coder aDecoder: NSCoder) { print("init coder style") super.init(coder: aDecoder) tap = UITapGestureRecognizer(target: self, action: Selector("handleTap:")) } ... ... }

Además, al llamar al inicializador de superclase, asegúrese de no pasar simplemente nil para nibName y bundle . Debes dejar pasar lo que fue pasado.