What Code in Newly Created Project Call Window? - objective-c

If I create a new project in xcode, there will be a main xib
In main xib there is an object called window.
I did an experiment where I remove the _window outlet from the automatically generated code.
#interface SDAppDelegate : NSObject <NSApplicationDelegate>
//#property (assign) IBOutlet NSWindow *window;
#end
I run the program and voila, that stupid window is still opened. The only way to make sure it's not opened is by deleting the window.
What part of the code display window? How do the delegate knows which window to open?
I do not want to show any window when application launch. I may want to show some windows when applications select preferences, for example.

NSApp loads your main XIB, and the window in it is set to be visible on launch, so it is. None of your code is involved in this process at all.

Related

How to reference an IBOutlet in an NSObject that is defined in a different NSObject

In a Mac Cocoa program, I have an AppController NSObject which performs most app functions and utilizes a MainMenu.xib file to conduct most interaction with the user.
However, I would like to announce error conditions encountered in that AppController with a separate pop up window which has a text field in its window to display the error.
That text field in the separate pop up window is not recognized in the AppController.
Do I need to somehow make the pop up window's controller a delegate or should the AppController be a delegate of the pop up window controller?
Will that make the IBOutlet of the pop up's text field visible to the AppController?

NSWindow bind load event for control and logic initialization

I just started working on an OSX application, first time in objective-c. I need to make a window that will display all the network interfaces available on the computer.
So far
I have an AppDelegate that pretty much does nothing
I have set the Main nib file base name to my main window, which is a xib, header and implementation file
I made my xib window inherit from my class and added the outlets I needed using right-click drag (worked well, I assumed I was correct until then)
The issue
I can't seem either override or bind the load event of the window, where I want to load the text in my label.
I've seen some people use a NSWindowController, but I don't think I need this.
My question
Is it required to have a NSWindowController PLUS a NSWindow class? I feel there are too many files for a single window. I have the xib and two .h/.m files... If it's not required, how can I get notified when the window loads?
The question wether you need NSWindowController(s) or not depends on the complexity of your application.
If your app is only a small utility using a single window, you might get away with setting up your UI in MainMenu.xib and connect it to some IBOutlets in your AppDelegate.
But the above approach gets messy soon when your app becomes more complex. To tame that complexity, you can create dedicated NSWindowController classes (e.g. one per window). Those window controllers could manage a hierarchy of child NSViewControllers to further split up your complexity.
If it's not required, how can I get notified when the window loads?
The default Xcode template should have created an AppDelegate.m file. You can add code to initialize your UI in
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
At this point the window has been fully loaded and
#property (weak) IBOutlet NSWindow *window;
should point to your window instance.

How to close window OSX?

I wanted to create an application that mainly only involves the status bar. So far I have created the status bar item using NSMenu and NSStatusBar and I have also removed the dock icon with this bit of code on load:
[NSApp setActivationPolicy: NSApplicationActivationPolicyAccessory];
But what I still have is the NSWindow appearing when opening the app.
How can I prevent this? I also would like to be able to re-open it.
I have come up with a horrible way to close it:
[_mainView setFrame:CGRectMake(0, 0, 0, 0)];
Where _mainView is the main NSView in my viewcontroller that is conected to the nswindow.
I then want to be able to open the window again but with this time a table. But I get the error:
<Warning>: void CGSUpdateManager::log() const: conn 0x18de3 token 0x31fffffffffdafd
When resetting the frame back to the original size.
Also if I close the NSView that then means I can't re-open the view again.
This is a long winded explanation of an application that can control whether the window the viewcontroller is in, is opened or close.
To make a NSStatusBar item app that only shows in the status bar and not in the Dock or Application Tabbing. And not show any of the normal menus. i.e file,edit,view and so on..
You need to add the Application is agent (UIElement) - (Boolean) YES key - value to the application info.plist.
And also make sure that the windows 'visible At Launch' is switch off in the attribute inspector.
Update:
In a none storyboard application (OS X)
Setting the 'visible At Launch' to off in IB for a window, will stop the window appearing at launch.
But with a storyboard application. This will not work.
The 'visible At Launch' is already set to be off. But regardless of that, the window will always show.
(I think this is part of the design of storyboards and Human interface guidelines by apple. Maybe because they stem from iOS and there should always be a window present.)
There are possibly a few ways of changing this behaviour but I found that if you uncheck the initial Controller in the Attributes Inspector for the NSWindowController
This will stop the window showing up at launch. Which makes sense since the app now does not have any instructions to show anything initially.
To open the window you can simply link a menu item to the NSWindowController's Presenting Segue Show: method in IB.
If you want to open the window programmatically, then you have to re point to the controller in the code.
In IB select the NSWindowController again
Go to the Identity Inspector.
Give the Storyboard ID the identity "Main"
Now go to your AppDelegate.h file and add a the Property and IBAction:
#property (strong) IBOutlet NSWindowController *winController;
-(IBAction)showWindow:(id)sender;
Then go to the AppDelegate.m file and add this code in the applicationDidFinishLaunching
NSStoryboard *storyBoard = [NSStoryboard storyboardWithName:#"Main" bundle:nil];
NSWindowController * main = [storyBoard instantiateControllerWithIdentifier:#"Main"];
_winController = main;
(note just adding the controller by linking it directly with a property in the AppDelegate did not work for me)
Now add the IBAction code to the AppDelegate.m
-(IBAction)showWindow:(id)sender {
[_winController showWindow:self];
}
You will need to link the IBAction as normal to which ever menu item you want to open the window via IB.

Window-less Cocoa application

I'm a complete beginner in Objective-C and Cocoa.
I would like to create a window-less application, which just shows a NSStatusItem in the system tray. The tray works fine, however, there is one problem.
For some reason my application automatically creates a window for me, which I do not want.
I thought it was caused by the automatic Interface Builder template created when I created the application in Xcode, so I deleted the .nib file from the project. However the window still gets created.
The only lines that contain a reference to the window are in the header:
NSWindow *window;
#property (assign) IBOutlet NSWindow *window;
and in the implementation file:
#synthesize window;
Both were added automatically, I did not write this.
How do I just stop the app from creating a window? I even tried to removing all references to window from the code, including the NSWindow *window, but the window still got created.
My temporary fix right now is to call [window close]; in the application, but surely there is a better way?
My suspicion is that nothing in your code is creating the window. When you create a new Cocoa Xcode application, Xcode sets up an XIB with your interface for you. Open up MainMenu.xib (should be under Resources) in interface builder and delete the window that it throws in by default.
If you don't want to show a window you may consider run your application in background. That will stop the window to appear.
In order to run your application in the background, set YES to "Application is background only" in your app's PLIST file
Return false in your NSDocument subclass' windowNibName method.

Cocoa Application Template - MainMenu.xib - Main Window

When you create a new application in Xcode, it automatically creates a AppDelegate and a MainMenu.xib. The latter also contains the application main window, which is linked to the AppDelegate as an IBOutlet.
What I tried to do is, use a MainWindow from a different xib-file. However, there's absolutely nothing I can do to prevent Cocoa from showing the first window it created in the first place, even if I remove the IBOutlet link and comment it out in the source file and what not...
Hope someone can explain this, as it has been bugging me for a while now...
Whether or not a window in a XIB is shown at launch is not controlled by an explicit code, but instead controlled by the state of the window "freeze-dried" in the XIB.
More concretely, in an inspector of an NSWindow in the Interface Builder, you have the option called Visible at launch under the heading Behavior.
When the Cocoa system loads a nib and encounters a window with this bit on, it just shows it on the screen. It's independent of whether you have IBOutlet or not. You see, it's also the Cocoa system which sets UI objects to IBOutlets when it loads a nib... it can do whatever it wants.