2015-06-06 17 views
33

Non riesco ad aggiungere il metodo init alla seguente classe UIViewController. Ho bisogno di scrivere del codice nel metodo init. Devo scrivere il metodo init (coder)? Anche quando aggiungo i metodi di codificatore e decodificatore, continuo a ricevere errori. Ho anche provato ad usare il metodo init senza parametri ma anche quello non sembra funzionare.Come scrivere i metodi init di un UIViewController in Swift

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:")) 
    } 

... 
... 
} 

Se chiamo il metodo super.init() senza parametri l'errore è "Deve chiamare un inizializzatore designato di classe super" e se mi passate il parametro pennino e pacchetto, poi errore è "Richiesto init initializer (coder)".

Anche quando aggiungo init (coder) e init (decoder) non funziona.

+0

Qual è l'errore? –

+0

devi provare richiesto init. Ho aggiunto la risposta @ankit –

+0

Che cosa vuoi aggiungere esattamente nel tuo 'init()'? Se è solo il gesto del tocco, lo si può fare anche in 'viewDidLoad()', o addirittura renderlo pigro var. – Eendje

risposta

4

Credo che bisogna aggiungere

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

o

convenience init() { 
    self.init() 
} 

Devi scrivere troppo init. Non rimuovere lo

var tap: UITapGestureRecognizer? 

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

Speranza che aiuta

+3

Viene visualizzato l'errore "È necessario chiamare un inizializzatore designato della superclasse" –

6

Si può solo creare un inizializzatore convenienza, invece, inizializzatori di convenienza non sostituiscono l'init() invece è solo la chiama rendendo le cose più facili.

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

L'app si arresta in modo anomalo perché tap è nullo anche se a esso è stato assegnato un valore in init. –

+0

stai provando ad usare il tocco da un'altra classe? – Icaro

+0

tap è dichiarato nella stessa classe .. proprio come il tuo codice. –

37

ho usato:

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

Qualcuno ha suggerito:

convenience init(){ 
    self.init() 
} 

Ma questo ti dà un ciclo infinito.

+1

Questa dovrebbe essere la risposta corretta. –

+0

Viene visualizzato l'errore "Argomento passato per chiamare che non richiede argomenti" nell'istruzione "self.init (nibName: nil, bundle: nil)". – RenniePet

+0

Non viene chiamato dal mio controller. – Jonny

13

è necessario sostituire il init(nibName:bundle:) inizializzatore, e fornire dell'inizializzatore init(coder:) richiesta, e inizializzare tap in ciascuno di essi:

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:")) 
    } 
... 
... 
} 

Inoltre, essere sicuri quando si chiama l'inizializzatore superclasse che non si basta passare nil per il nibName e bundle. Dovresti passare tutto ciò che è stato passato.

+2

All'interno di 'init richiesto (coder aDecoder: NSCoder)', si ha 'super.init()' ... non dovrebbe essere 'super.init (coder: aDecoder)'? –

+0

In effetti c'erano due errori di battitura nell'esempio di codice. Puoi vedere facilmente gli errori semplicemente usando la funzione di completamento automatico in Xcode. Roman, se vedi questo, ho modificato gli errori di battitura. Naturalmente sentiti libero di cambiare o di rilassarti. Questa è l'unica risposta corretta qui, quindi ho corretto gli errori di battitura, acclamiamo gli uomini. – Fattie

12

Tutte queste risposte sono mezze risposte. Alcune persone stanno sperimentando cicli infiniti in post correlati perché stanno aggiungendo solo lo convenience init() (si chiama in modo ricorsivo se non fornisce un distinto metodo init() per invocarlo), mentre altre persone stanno trascurando di estendere la superclasse. Questo formato combina tutte le soluzioni per soddisfare completamente il 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 
} 

Edit: Inoltre, se si desidera inizializzare tutte le proprietà di classe che utilizzano parametri passati nel vostro metodo di convenience init() senza tutte le ignorati init() metodi lamentarsi, allora è possibile impostare tutte quelle proprietà come implicitamente optional da scartare, che è uno schema used by Apple themselves.

0

Mi sono imbattuto in questa domanda di te che ti chiedeva una lunga strada. Ma nessuno ha fornito una risposta di base alla domanda. È fondamentale in Swift che: - La sottoclasse deve inizializzare le sue variabili prima che l'inizializzazione di super classe sia completa.

Quindi come Ankit Goel parlano del crollo: - "Deve chiamare un inizializzatore designato della superclasse"

codice Quindi aggiornato sarebbe: -

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:"))) 
}} 
Problemi correlati