2016-02-29 15 views
16

Wenn ich meine benutzerdefinierte IBDesignable-Ansicht in ein Storyboard oder eine andere Schreibfeder einfüge, stürzt der Agent ab und löst eine Ausnahme aus, weil die Schreibmarke nicht geladen werden kann.Fehler beim Rendern der Instanz von ClassName: Der Agent hat eine Exception loading nib in bundle geworfen

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'

Hier ist der Code, den ich verwende, um die Spitze zu laden:

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

Die Ansicht Lasten von der Spitze richtig, wenn ich im Simulator laufen, warum wird es nicht in Interface Builder angezeigt werden?

Antwort

32

Wenn der Interface Builder Ihre IBDesignable Ansichten rendert, verwendet er eine Hilfsanwendung, um alles zu laden. Das Ergebnis davon ist, dass die mainBundle zur Entwurfszeit auf die Hilfs-App bezogen ist, und es ist nicht die mainBundle Ihrer App. Sie können sehen, dass der Pfad in dem Fehler erwähnte nichts mit Ihrer App zu tun hat:

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

Wenn die Spitze Laden, sind Sie auf der Tatsache, dass unter Berufung bundle: nil standardmäßig auf Ihre App mainBundle zur Laufzeit übergeben.

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

Also statt, müssen Sie hier die richtige Bündel passieren. Befestigen Sie die obige Zeile mit dem folgenden:

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

Das wird Interface Builder laden Sie Ihre Feder aus dem gleichen Paket wie Ihre benutzerdefinierte Ansicht Klasse.

Dies gilt für alle Elemente, die von einem Bundle in Ihrer benutzerdefinierten Ansicht geladen wurden. Zum Beispiel lokalisierte Zeichenfolgen, Bilder usw. Wenn Sie diese in Ihrer Ansicht verwenden, stellen Sie sicher, dass Sie denselben Ansatz verwenden und das Paket explizit für die benutzerdefinierte Ansichtsklasse übergeben.

+4

Vielen Dank! Dies fehlt in einer überraschenden Anzahl von Tutorials. – GoldenJoe

+2

Wenn ich könnte, hätte ich dir 100+ Punkte gegeben. Ich habe damit viel Zeit verloren. –

+0

Ich bin froh, dass ich helfen konnte, Laura und Joe! –

3

Der gleiche Standpunkt mit "Josh Heald", können wir nicht Nil für Bündel übergeben. Und dieser für wer im Objekt - 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

Das ist etwa 1 Jahr alt, und es ist nicht die vollständige Lösung für mich, aber das brachte mich über die große Hürde, die Feder zu laden. Danke!!! – Armand