xcode 6 IB_DESIGNABLE - nicht laden von Ressourcen aus bundle im Interface builder
Ich versuche, ein benutzerdefiniertes Steuerelement, das updates live im Interface Builder mit der neuen IB_DESIGNABLE beschriebene option hier.
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGRect myFrame = self.bounds;
CGContextSetLineWidth(context, 10);
CGRectInset(myFrame, 5,5);
[[UIColor redColor] set];
UIRectFrame(myFrame);
NSBundle *bundle = [NSBundle mainBundle];
NSString *plistPath;
plistPath = [bundle pathForResource:@"fileExample" ofType:@"plist"];
UIImage *tsliderOff = [UIImage imageNamed:@"btn_slider_off.png"];
[tsliderOff drawInRect:self.bounds];
}
Wenn ich in den simulator, bekomme ich einen roten Kasten mit meinem Bild in der Mitte (wie erwartet):
Aber wenn ich versuche mit dem Interface-Builder, es zeigt nur, wie ein rotes Feld (kein Bild in der Mitte):
Wenn ich debug es: Editor->Debug-Selected Views, es zeigt, dass etwas geladen aus dem bundle ist gleich null. Die plistPath und tsliderOff beide erscheinen als null.
Machte ich sicher, dass btn_slider_off.png wurde in die Ziele->myFrameWork->Build-Phasen->Copy Bundle Resources.
Jede Idee, warum der Interface Builder nicht sieht, dass die png-Datei während der Bearbeitung, zeigt aber ok, wenn ausgeführt? "Erstellen einer Benutzerdefinierten Ansicht, dass die Macht im Interface Builder" ist ein wenig eingeschränkt, wenn ich nicht laden kann auch keine Bilder zu Rendern...
Bearbeiten, basiert auf der Lösung von rickster
rickster wies mich auf die Lösung - das problem ist, dass die Dateien nicht live im mainBundle, in der Sie Leben [NSBundle bundleForClass:[self class]]; Und es scheint, dass [UIImage imageNamed:@"btn_slider_off.png"] verwendet automatisch mainBundle.
Der folgende code funktioniert!
#if !TARGET_INTERFACE_BUILDER
NSBundle *bundle = [NSBundle mainBundle];
#else
NSBundle *bundle = [NSBundle bundleForClass:[self class]];
#endif
NSString *fileName = [bundle pathForResource:@"btn_slider_off" ofType:@"png"];
UIImage *image = [UIImage imageWithContentsOfFile:fileName];
[image drawInRect:self.bounds];
- Tut dies immer noch gilt für Xcode 6.0.1, IB_DESIGNABLE Klassen, die sich nicht in einen Rahmen? Ich kann es nicht funktionieren. Was ist es schlimmer, ich kann nicht Debuggen der Ansicht, wenn ich versuche zu Debuggen mit Haltepunkt Xcode stürzt mit dem spinning beach ball of death.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Als bei dieser Frage wurde zunächst gebeten, die Schaffung eines IB-gestaltbares Kontrolle erforderlich, Verpacken es in einen Rahmen Ziel. Sie müssen nicht mehr, das zu tun — der Versand von Xcode 6.0 (und höher) Vorschau IB-gestaltbaren-Steuerelemente in Ihrer app Ziel zu. Jedoch, das problem und die Lösung sind identisch.
Warum?
[NSBundle mainBundle]
gibt die primären Bündel der aktuell Laufenden app.Wenn Sie anrufen, die von einem Rahmen, die Sie bekommen, einen anderen bundle zurückgegeben, welche app ist die Belastung des Rahmens. Wenn Sie führen Sie Ihre app, Ihre app lädt die Rahmen. Wenn Sie das Steuerelement in IB, eine Besondere Xcode-Helfer-app lädt die Rahmen. Auch wenn Ihr IB-gestaltbares Kontrolle ist in Ihrem app-target, Xcode ist die Schaffung eines speziellen Helfer-app ausführen, um das Steuerelement innerhalb des IB.
Die Lösung? Rufen Sie
+[NSBundle bundleForClass:]
statt (oderNSBundle(forClass:)
Swift). Dadurch bekommt man das bundle enthält den ausführbaren code für welche Klasse Sie angeben. (Sie können[self class]
/self.dynamicType
es, aber Vorsicht, das Ergebnis ändert sich für Unterklassen definiert, die in verschiedenen bundles.)Wenn Sie mit der framework-Ansatz — die nützlich sein können für einige apps, obwohl es nicht länger erforderlich, für IB-gestaltbaren — Steuerung- Sie stellen Bild-Ressourcen im gleichen Rahmen mit dem code, der Sie verwendet. Wenn Ihr framework-code erwartet, dass das verwenden von Ressourcen zur Laufzeit bereitgestellt von welcher app lädt das framework, das beste, was zu tun, für die es IB-gestaltbar ist es imitieren. Umsetzung der
prepareForInterfaceBuilder
Methode in Ihr Steuerelement und laden von Ressourcen aus einem bekannten Ort (wie die framework-bundle oder einen statischen Pfad ein, in Ihrem Xcode-Arbeitsbereich).ClassName.self
das problem gelöst.ClassName.self
(Swift) /[ClassName class]
(ObjC), wenn Sie ausdrücklich, dass das bundle in dieClassName
definiert ist. Verwendenself.dynamicType
(Swift) /[self class]
(ObjC), wenn Sie möchten, Unterklassen vonClassName
zu verwenden automatisch Ihre eigenen bundles statt.Ich lief in ein ähnliches problem in Swift. Wie der Xcode 6 beta 3, die Sie nicht brauchen, um den Rahmen zu bekommen live rendering. Jedoch, Sie noch zu tun haben mit dem bundle problem für die Live-Ansicht, so dass Xcode weiß, wo Sie zu finden Vermögen. Vorausgesetzt, "btn_slider_off" ist ein Bild gesetzt in Bildern.xcassets dann können Sie dies tun, Swift für live-rendering und es wird funktionieren, wenn die app ausgeführt wird, die normalerweise als gut.
Warnung über das oben genannte Paket/Pfad-Auflösung, während in IB_DESIGNABLE:
XCode nicht beheben, eine Ressource, wenn der Aufruf enthalten, die bei der Initialisierung der UIView. Könnte ich nur XCode zu beheben, ein Pfad, während in drawRect:
Fand ich eine tolle /einfache Problemumgehung für das obige bundle-Auflösung-Techniken, einfach benennt eine
IBInspectable
- Eigenschaft, um einUIImage
, dann geben Sie das Bild im Interface Builder. Ex:Ich habe es behoben mit dem folgenden Codezeile:
Nach der Umsetzung diese Weise werden die Bilder korrekt angezeigt im Interface Builder
IN SWIFT 3.0 der code von @rickster hat sich verändert:
Ich hatte auch das gleiche problem : bei dieser Suche Antwort und folgende WWDC 2014-was ist neu im Interface Builder.
Ich löste es so: