2010-03-11 3 views
5

In meinem folgenden Code ist CustomWindow eine Unterklasse von NSWindow.Zeiger auf NSWindow Xib nach dem Laden?

CustomWindow *window = [[CustomWindow alloc] init]; 
if (![NSBundle loadNibNamed:@"NibName" owner:window]) 
[window center]; // doesn't work 

Wie bekommt man einen Zeiger Ihre XIB zu steuern, nachdem sie geladen werden, so dass Sie Dinge tun, wie die NSWindow Zentrierung (ich meine die serialisierte ein, die innerhalb des XIB befindet)?

Was mache ich hier falsch?

Antwort

16

Sie sollten eine NSWindowController Unterklasse verwenden. NSWindowController wurde speziell entwickelt, um genau das zu erreichen, was Sie erreichen wollen, und löst mehrere Probleme, denen Sie begegnen werden, wenn Sie die Spitze direkt mit den Methoden von NSBundle laden. Im Allgemeinen sollten Sie immer eine NSWindowController Unterklasse verwenden, um Windows zu verwalten.

eine Unterklasse von NSWindowController erstellen:

@interface MyWindowController : NSWindowController {} 
@end 

@implementation MyWindowController 
- (id)init 
{ 
    self = [super initWithWindowNibName:@"MyWindow"]; 
    if(self) 
    { 
     //initialize stuff 
    } 
    return self; 
} 
//this is a simple override of -showWindow: to ensure the window is always centered 
-(IBAction)showWindow:(id)sender 
{ 
    [super showWindow:sender]; 
    [[self window] center]; 
} 
@end 

In Interface Builder, stellen Sie die Klasse von Besitzer DateiMyWindowController und schließen Sie das window Ausgang Datei Besitzer zum Fenster-Objekt in Ihrer Spitze zu sein.

Anschließend können Sie das Fenster angezeigt werden, indem Sie diese:

MyWindowController* controller = [[MyWindowController alloc] init]; 
[controller showWindow:self]; 
+0

Ich habe alles gemacht, was Sie schon gesagt haben, außer "Verbinden Sie den Fensterausgang des Dateibesitzers". Sobald ich das gemacht habe, hat alles funktioniert. Vielen Dank! +1 und Tick. –

+0

Deaktivieren Sie die Eigenschaft "Wiederherstellbar" des Fensters in IB. –

+0

@KeithSmiley Welcher Editor ist die 'Restorable'-Eigenschaft, oder gilt dies nicht mehr für Xcode 5.x? –

1

Wahrscheinlich möchten Sie Ihr Fenster nicht zum Eigentümer der Datei machen. Normalerweise würden Sie dort self oder ein Controller-Objekt übergeben. Wenn self oder das Controller-Objekt ein CustomWindow IBOutlet hat, wird es beim Aufruf von loadNibNamed: angeschlossen. Überprüfen Sie this post zum Beispiel Code.

+0

CustomWindow ist das Controller-Objekt. Es enthält IBOutlets, die beim Ausführen der Anwendung angeschlossen werden. Die Steuerelemente im Fenster funktionieren alle. Kann einfach nicht herausfinden, wie man es zentriert. –

0

Ein XIB ist ein Container für Objekte, es ist nicht gleich einem Fenster. Sie können ein XIB nicht zentrieren, Sie können nur ein in einem XIB enthaltenes Fenster zentrieren.

Auch die Objekte in der XIB werden erstellt, wenn Sie sie laden. Sie übergeben kein Objekt als Eigentümer, das dann für eines der Objekte in der XIB steht, stattdessen verwenden Sie IBOutlets, um Verweise auf die neuen Objekte zu erhalten, die beim Laden der XIB erstellt wurden, und Sie können dann mit ihnen interagieren.

Das Eigentümerobjekt der Datei ist ein spezielles Objekt in XIBs, da es das einzige Objekt ist, das nicht erstellt wurde und das Sie angeben können, indem Sie es an loadNibNamed:owner: übergeben. Es ist Ihr Gateway zwischen den von XIB erstellten Objekten und Ihrer Anwendung.

Normalerweise ist das Eigentümerobjekt eine Art von Controller-Klasse. Legen Sie die Klasse des Eigentümers des Dateibesitzers in Interface Builder auf Ihre Controller-Klasse fest und definieren Sie dann einige IBOutlets in der Klasse. Sie werden im Interface Builder auf dem Besitzer der Datei angezeigt und Sie können Ihre Objekte in der XIB mit ihnen verbinden.

Schließlich, wenn Sie Ihr Controller-Objekt an loadNibNamed:owner: übergeben, wird Cocoa Ihre IBOutlets mit den neu erstellten Objekten verbinden und Sie können sie verwenden, um mit ihnen interagieren, z. um ein Fenster in Ihrem XIB zu zentrieren.

+0

Sie beschreiben, was ich bereits eingerichtet habe. Es gibt keine Probleme mit IBOutlets und ich versuche nicht, einen Zeiger auf ein XIB zu bekommen. Die XIB enthält ein NSWindow, das ich einen Zeiger auf –

+0

haben möchte. Das ist, was Sie in IB für den "Besitzer der Datei" verwenden. Es ist ein Proxy für das Objekt, das Sie an die loadNibNamed: -Methode übergeben. Siehe die andere Antwort. –

+0

Ja das ist was ich tue. Es stellte sich heraus, dass das Windows-Fenster "Dateibesitzer" nicht mit dem Fensterobjekt des XIB verbunden war. –

2

In meinem Code unten ist CustomWindow eine Unterklasse von NSWindow.

CustomWindow *window = [[CustomWindow alloc] init]; 
if (![NSBundle loadNibNamed:@"NibName" owner:window]) 
[window center]; // doesn't work 

Wie bekommt man einen Zeiger Ihre XIB zu steuern, nachdem sie geladen werden, so dass Sie Dinge tun, wie die NSWindow innerhalb des XIB Zentrierung?

„innerhalb des XIB die NSWindow Zentrierung“ macht keinen Sinn (Sie es auf dem Bildschirm Zentrum würde), wenn Sie das NSWindow Objekt bedeuten Zentrierung, die innerhalb des xib ist, wobei in diesem Fall, warum Sie erstellen ein anderes NSWindow (CustomWindow) Objekt außerhalb der Xib?

Denken Sie daran, dass eine Nib (oder Xib) ein Archiv von Objekten ist. Wenn Sie ein Fenster verwenden möchten, das Sie in Ihrer Schreibfeder haben, müssen Sie eine Steckdose erstellen, die auf dieses Fenster zeigt. Legen Sie die Klasse des Dateibesitzers als die Klasse fest, in der Sie die Steckdose hinzugefügt haben IB, und ernennen Sie das Objekt mit der Steckdose als Eigentümer der Datei, indem Sie es an das Argument owner: übergeben. Dieses Objekt als Eigentümer ist dann für die Arbeit mit dem Fenster verantwortlich. Es kann sein (normalerweise, in meinem Code) das gleiche Objekt, das die Feder lädt.

Auch init funktioniert nicht auf NSWindow; Sie müssen initWithContentRect:styleMask:backing:defer: oder initWithContentRect:styleMask:backing:defer:screen: verwenden. Die Verwendung von init wäre nur dann gültig, wenn Sie in CustomWindow selbst init implementiert und einen dieser beiden Selektoren für die Nachricht [super init…] verwendet haben.