views:

401

answers:

4

In my code below, CustomWindow is a subclass of NSWindow.

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

How do you get a pointer to control your XIB after you load it so you can do things such as centering the NSWindow (I mean the serialised one that resides inside the XIB)?

What am i doing wrong here?

+1  A: 

You probably don't want to make your window the File's Owner. Normally you would pass self or some controller object there. Then if self or that controller object has a CustomWindow IBOutlet, it will get hooked up when you call loadNibNamed:. Check out this post for example code.

Carl Norum
CustomWindow is the controller object. It contains IBOutlets that get hooked up when I run the application. The controls on the window all work. Just can't figure out how to centre it.
Brock Woolf
A: 

A XIB is a container for objects, it's not equal to a window. You can't center a XIB, you can only center a window contained in a XIB.

Also, the objects in the XIB are created when you load it. You don't pass an object as owner that then stands in for one of the objects in the XIB, you instead use IBOutlets to get references to the new objects created when loading the XIB and then you can interact with them.

The File's Owner object is a special object in XIBs, as it's the only object that is not created and that you can specify by passing it to loadNibNamed:owner:. It's your gateway between the XIB-created objects and your application.

Usually, the owner object is some kind of controller class. Set the File's Owner's class in Interface Builder to your controller class, then define some IBOutlets in the class, they will show up in Interface Builder on the File's Owner and you can connect your objects in the XIB to them.

Finally, when you pass your controller object to loadNibNamed:owner:, Cocoa will connect your IBOutlets to the newly created objects and you can use them to interact with them, e.g. to center a window in your XIB.

Adrian
You describe what I already have setup. There are no problems with IBOutlets and I'm not trying to get a pointer to a XIB. The XIB contains an NSWindow which I want a pointer to
Brock Woolf
That's what you use the "File's Owner" in IB for. It's a proxy for the object you pass into the loadNibNamed: method. See the other answer.
Nicholas Riley
Yes that's what I though. Turns out the issue was that I didn't have the File's Owner window outlet connected to the XIB's window object.
Brock Woolf
+1  A: 

You should be using an NSWindowController subclass. NSWindowController is specifically designed to do exactly what you want to achieve and solves several problems that you will run into if you load the nib directly using the methods of NSBundle. You generally should always use an NSWindowController subclass to manage windows.

Create a subclass of NSWindowController:

@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, set the class of File's Owner to be MyWindowController and connect the window outlet of File's Owner to the window object in your nib.

You can then display the window by doing this:

MyWindowController* controller = [[MyWindowController alloc] init];
[controller showWindow:self];
Rob Keniger
I was doing everything you said already, except for "connect the window outlet of File's Owner". Once I did that everything worked. Thanks a bunch! +1 and Tick.
Brock Woolf
A: 

In my code below, CustomWindow is a subclass of NSWindow.

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

How do you get a pointer to control your XIB after you load it so you can do things such as centering the NSWindow inside the XIB?

“centering the NSWindow inside the XIB” makes no sense (you would center it on the screen), unless you mean centering the NSWindow object that is inside the xib, in which case, why are you creating another NSWindow (CustomWindow) object outside of the xib?

Remember that a nib (or xib) is an archive of objects. If you want to use a window that you have in your nib, you need to create an outlet to point to that window, set the class of the File's Owner to be the class where you've added the outlet, hook up the outlet in IB, and appoint the object with the outlet as the File's Owner by passing it to the owner: argument. That object, as the owner, will then be responsible for working with the window. It may be (usually is, in my code) the same object that loads the nib.

Also, init doesn't work on NSWindow; you must use initWithContentRect:styleMask:backing:defer: or initWithContentRect:styleMask:backing:defer:screen:. Using init would only be valid if you've implemented init yourself in CustomWindow, and used one of those two selectors for the [super init…] message.

Peter Hosey