23

I'm trying to change my windows content, from other class , that is subclass of NSViewController.I'm trying code below, but it doesn't do anything.

[NSApplication sharedApplication]mainWindow]setContentView:[self view]]; //code in NSViewController

[NSApplication sharedApplication]mainWindow] // returns null

I tried to add

[window makeMainWindow];

in App Delegate class, but it won't help.

Did I miss something?

P.S. Also I'm using code below to call any delegate function in my class,

 [(appDelegate *) [[NSApplication sharedApplication]delegate]MyMethod];

but I wonder is there something better, wihtout importing delegate class. Something like this

[[NSApplication sharedApplication]delegate]MyMethod];

(it gives warning)

User1234
  • 2,362
  • 4
  • 27
  • 57

4 Answers4

43

For the mainWindow method the docs say:

This method might return nil if the application’s nib file hasn’t finished loading, if the receiver is not active, or if the application is hidden.

I just created a quick test application and I placed the following code:

NSLog(@"%@", [[NSApplication sharedApplication] mainWindow]);

into my applicationDidFinishLaunching:aNotification method, and into an action method which I connected to a button in the main window of my application.

On startup, the mainWindow was nil, but when I click the button (after everything is up and running and displayed), the mainWindow was no longer nil.

NSApplication provides other methods which you may be useful to you:

  • - windows - an array of all the windows;
  • – keyWindow - gives the window that is receiving keyboard input (or nil);
  • – windowWithWindowNumber: - returns a window corresponding to the window number - if you know the number of the window whose contents you wish to replace you could use this;
  • – makeWindowsPerform:inOrder: - sends a message to each window - you could use this to test each window to see if it's the one you are interested in.

With regard to calling methods on the delegate, what you say gives a warning works fine for me. For example, this works with no warnings:

NSLog(@"%@", [[[NSApplication sharedApplication]delegate] description]);

What exactly is the warning you receive? Are you trying to call a method that doesn't exist?

Maurice Kelly
  • 1,462
  • 12
  • 15
  • Thanks a lot.I have just one window. So probably I will use windows, to get in Array, and will use first object in Array. About methods on the delegate, did you try it from different class like viewcontroller? when I call it, it works fine, but it gives a warning, that delegate may not respond to that Method. – User1234 Oct 01 '11 at 23:16
  • I see what you mean now about the delegate calls. Unfortunately the [[NSApplication sharedApplication] delegate] message will always return an object of type NSApplicationDelegate. You will have to cast it to your app delegate if you want to send it messages which are specific to your app delegate. You might want to ask this as a separate question? – Maurice Kelly Oct 01 '11 at 23:49
  • I think the only way to do that is cast NSApplicationDelegate to specific delegate, and import it in class. Thanks. – User1234 Oct 02 '11 at 03:08
  • There's one another way ! you can [[NSApplication sharedApplication]delegate]performSelector:@selector(selectorName)]; If you know the selector name in your delegate there's no need to include the appdelegate header and typecast. This will work. – Nofel Mahmood Mar 21 '15 at 08:24
  • How about in Swift Playground? How can I get a non-nil mainWindow? – allenlinli Aug 05 '16 at 01:17
22

Fighting with MacOS just figured this out.

Apple's quote:

mainWindow

Property

The app’s main window. (read-only)

Discussion

The value in this property is nil when the app’s storyboard or nib file has not yet finished loading. It might also be nil when the app is inactive or hidden.

If you have only one window in your application (which is the most used case) use next code:

NSWindow *mainWindow = [[[NSApplication sharedApplication] windows] objectAtIndex:0];

Promise it won't be nil, if application has windows.

Community
  • 1
  • 1
Borzh
  • 5,069
  • 2
  • 48
  • 64
  • I'm commenting on a question from 3 years ago, but this doesn't seem to work either. Shouldn't it return something, seeing as the ViewController the code goes into is done loading by the time it tries to get the window? – Naoto Ida Jul 17 '15 at 06:25
  • You you paste this code into viewDidLoad it should work. Of course if you have no windows in your app, then it will be nil. – Borzh Jul 17 '15 at 17:21
  • Thanks for replying. It is in one of of the tableView methods, as it is a delegate of NSTableView. So I don't know why it wouldn't work, with a window showing contents. – Naoto Ida Jul 18 '15 at 07:30
  • I'm pretty sure you can't promise that it won't be nil. – quemeful May 09 '16 at 12:50
  • Of course, it will be **nil** if application doesn't have any window... edited the answer accordingly. – Borzh May 09 '16 at 15:51
1

Swift flavored approaches for getting the main window (if present)

Application Main Window

guard let window = NSApplication.shared.mainWindow,
else {
    // handle no main window present
}
// ... access window here

Application Window Array

let windowArray: [NSWindow] = NSApplication.shared.windows
guard windowArray.count > 0 else {
    // hand case where no windows are present
}
let window = windowArray[0]
// ... access window here
marc-medley
  • 8,931
  • 5
  • 60
  • 66
0

If the window property isn't set yet, try delaying things until the app has finished loading, like so:

[myObject performSelector:@selector(theSelector) withObject:nil afterDelay:0.1];
Jeff
  • 2,659
  • 1
  • 22
  • 41