2016-01-07 18 views
13

Ho provato a creare la sottoclasse @IBDesignable UIView seguendo questo tutorial (link). La prima vista personalizzata va bene. Ma quando provo a farne un altro, ho degli errori. Per prima cosa ho ottenuto failed to update auto layout status: the agent crashed e Failed to render instance of .... In qualche modo ho iniziato a essere in grado di generare ed eseguire il progetto con questi errori, ma poi ricevo un nuovo errore - EXC_BAD_ACCESS ... sulla linea let view = nib.instantiateWithOwner(self, options: nil)[0] as! UIView. Ecco il metodo completo:Instantiate vista dal pennino genera errore

func loadViewFromNib() -> UIView { 

     let bundle = NSBundle(forClass: self.dynamicType) 
     let nib = UINib(nibName: "advancedCellView", bundle: bundle) 
     let view = nib.instantiateWithOwner(self, options: nil)[0] as! UIView 

     return view 
    } 

Con il primo UIView personalizzato non è un problema. Io uso lo stesso codice ..

enter image description here

Tutte le idee? Grazie

+1

Hai scritto "La prima vista personalizzata va bene". Significa che sei effettivamente in grado di caricare la vista una volta, ma poi se provi a caricarla di nuovo ottieni un errore? –

+1

Inoltre, quale è la ragione per usare 'NSBundle: forClass:' invece di accedere a 'NSBundle.mainBundle()'? Questo 'nib' è memorizzato in un altro pacchetto? –

+1

Ciò suggerisce che il problema non è con il codice che carica e istanzia il 'nib', ma con qualcosa nel file' xib' stesso. Hai modificato la 'classe' per la sottoclasse della vista nel generatore di interfacce per' xib'? –

risposta

29

Il metodo loadViewFromNib() che pubblichi sembra corretto, stai ricevendo il pacchetto correttamente e specificando il nome del pennino come stringa letterale, quindi dovrebbe trovare il pennino. Come ha commentato qualcun altro, probabilmente c'è qualcosa di sbagliato nella configurazione del pennino. Qui ci sono alcune cose da controllare:

  1. Si dovrebbe avere AdvancedCellView insieme come Proprietario classe personalizzata del file nella finestra di ispezione identità.
  2. Verificare che il modulo sia corretto, in genere lo si vuole vuoto.
  3. La classe personalizzata per la vista non deve essere impostata, è sufficiente lasciarla come predefinita (UIView). Se hai un nome più descrittivo di "Visualizza" nella barra laterale, probabilmente è sbagliato.
  4. Verificare di avere un solo oggetto di livello superiore nel pennino. La barra laterale dovrebbe apparire così, senza altre voci, quando l'albero della vista è collassato.

Nib hierarchy with only one top level view

N.B. Questa risposta è correlata al tutorial a cui l'OP si è collegato, e non l'unico modo corretto di impostare un pennino.

+0

Dato che il codice dell'OP sta caricando manualmente il pennino e impostando direttamente la proprietà 'view', non è chiaro se sia necessario impostare la classe Owner's del file nel file pennino. In ogni caso non influenzerebbe il comportamento in fase di esecuzione, ma solo la possibilità di effettuare connessioni in Interface Builder. Tuttavia, non è corretto dire che la classe della vista non dovrebbe essere impostata nel pennino (se l'OP vuole che sia una sottoclasse di 'UIView'); che * avrebbe * influenzato il comportamento di runtime perché quell'informazione è usata dall'unarchiver per determinare quale classe istanziare. – jlehr

+0

Grazie, è la risposta corretta – Lachtan

+0

@jlehr true, non è sempre il caso che la classe non debba essere impostata nel pennino, ma l'OP stava seguendo un tutorial che gli aveva caricato la vista dal pennino nel 'init (frame :) 'e' init (coder:) 'metodi. In tal caso, l'impostazione della classe personalizzata per la vista determinerà un ciclo infinito durante il caricamento del pennino, a meno che non si disponga di un altro codice per impedirlo. –

0

Prova invece a farlo. funziona sempre per me:

let picker = NSBundle.mainBundle().loadNibNamed("advancedCellView", owner: nil, options: nil) 
let view = picker[0] as! UIView 

return view 

fatemi sapere se funziona

+0

Grazie per la risposta. Non funziona né nel primo UIView personalizzato. Lancia l'app di terminazione a causa dell'eccezione non rilevata 'NSUnknownKeyException', motivo: '[ setValue: forUndefinedKey:]: questa classe non è un valore chiave conforme alla codifica per la chiave captionLabel.'' – Lachtan

+0

Questo è un altro problema. Devi collegare l'etichetta nello storyboard alla tua classe di visualizzazione personalizzata. – brl214

2

Il metodo instantiateWithOwner(options:) restituisce un array, non una vista, in modo forzato avvilito per UIView non funzionerà mai. Invece, prova a trasmettere il tipo effettivo, [AnyObject].

Gli elementi nell'array corrispondono agli oggetti di livello superiore nel file pennino, pertanto la vista a cui si è interessati dovrebbe essere uno degli elementi dell'array. Dato il nome del tuo file pennino, con ogni probabilità ci sarà solo un oggetto di primo livello nella matrice - la cella che stai tentando di caricare. Assicurati che ci sia un solo oggetto di livello superiore nel file del pennino e che sia effettivamente un'istanza di una sottoclasse di UIView.

Si noti che l'implementazione è potenzialmente inefficiente. Se stai caricando più di una cella, dovresti memorizzare nella cache l'istanza UINib invece di crearne una nuova ogni volta. Nota che le classi di framework come UITableViewController hanno incorporato metodi per la registrazione dei pennini che si prendono cura di questi dettagli automaticamente, quindi potresti non aver bisogno di farlo da solo.

+1

Il metodo instantiateWithOwner (opzioni :) restituisce una serie di oggetti di livello superiore decompressi dal pennino, come dici tu. Tuttavia, se questi oggetti non hanno un set di classi personalizzate, saranno UIViews e il downcast funzionerà correttamente. Non penso che dovrebbe essere un downcast forzato, ma questo è un altro problema. –

+0

Heh, hai ragione - sembra che mi sia mancato il '[0]' lì. Aggiornerò la mia risposta – jlehr

0

Stavo guardando il tutorial e ho scoperto che se si sottoclasse l'elemento View nel proprio xib personalizzato, si otterrà l'errore. Assicurati di aver impostato il "Proprietario del file" solo sulla tua classe personalizzata.

enter image description here

Problemi correlati