2016-02-29 24 views
16

Quando includo la mia vista IBDesignable personalizzata in uno storyboard o in un altro pennino, l'agente si arresta in modo anomalo e genera un'eccezione perché non può caricare il pennino.Impossibile eseguire il rendering dell'istanza di ClassName: l'agente ha gettato un'eccezione che carica il pennino nel pacchetto

error: IB Designables: Failed to update auto layout status: The agent raised a "NSInternalInconsistencyException" exception: Could not load NIB in bundle: 'NSBundle (loaded)' with name 'StripyView'

Ecco il codice che uso per caricare il pennino:

override init(frame: CGRect) { 
    super.init(frame: frame) 
    loadContentViewFromNib() 
} 

required init?(coder aDecoder: NSCoder) { 
    super.init(coder: aDecoder) 
    loadContentViewFromNib() 
} 

func loadContentViewFromNib() { 
    let nib = UINib(nibName: String(StripyView), bundle: nil) 
    let views = nib.instantiateWithOwner(self, options: nil) 
    if let view = views.last as? UIView { 
     view.frame = bounds 
     view.autoresizingMask = [UIViewAutoresizing.FlexibleWidth, UIViewAutoresizing.FlexibleHeight] 
     addSubview(view) 
    } 
} 

La vista carichi dal pennino correttamente quando corro nel simulatore, perché non sarà che visualizza in Interface Builder?

risposta

32

Quando Interface Builder esegue il rendering delle visualizzazioni IBDesignable, utilizza un'applicazione di supporto per caricare tutto. Il risultato è che lo mainBundle in fase di progettazione è correlato all'app helper e non è l'mainBundle della tua app. Si può vedere che il percorso di cui l'errore non ha nulla a che fare con la vostra applicazione:

/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/Xcode/Overlays

Quando si carica il pennino, si sta contando sul fatto che il passaggio bundle: nil default per la vostra applicazione di mainBundle in fase di esecuzione.

let nib = UINib(nibName: String(describing: StripyView.self), bundle: nil) 

Quindi, è necessario passare il pacchetto corretto qui. Fissare la linea di cui sopra con il seguente:

let bundle = Bundle(for: StripyView.self) 
let nib = UINib(nibName: String(describing: StripyView.self), bundle: bundle) 

che renderanno Interface Builder caricare il tuo pennino dallo stesso fascio come la classe di visualizzazione personalizzata.

Si applica a tutto ciò che viene caricato da un pacchetto dalla vista personalizzata. Ad esempio, stringhe localizzate, immagini, ecc. Se le stai usando nella tua vista, assicurati di utilizzare lo stesso approccio e di passare esplicitamente nel pacchetto per la classe di visualizzazione personalizzata.

+4

Grazie! Questo manca da un numero sorprendente di tutorial. – GoldenJoe

+2

Se potessi, ti avrei dato più di 100 punti. Ho perso molto tempo con questo. –

+0

Contento di aver potuto aiutare, Laura e Joe! –

3

Lo stesso punto di vista con "Josh Heald", Non possiamo passare nil per bundle. E questo per chi in oggetto - C:

- (UIView *) loadViewFromNib{ 
NSBundle *bundle = [NSBundle bundleForClass:[self class]]; 
UINib *nib = [UINib nibWithNibName:NSStringFromClass([self class]) bundle:bundle]; 
UIView *v = [[nib instantiateWithOwner:self options:nil]objectAtIndex:0]; 
return v; 
} 
+0

Questo è circa 1 anno, e non è la soluzione completa per me, ma questo mi ha fatto superare l'ostacolo principale, di ottenere il pennino da caricare. grazie!!! – Armand