Cocoa Application Template - MainMenu.xib - Main Window - objective-c

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.

Related

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.

Using multiple windows with Storyboards (Mac OS X development)

I have two window controllers (with their own view controllers) on a storyboard.
In one window, I have the main program, a basic text editor with an NSTextView. In the other window, I have a single button.
I found out how to get the window to display by linking it to a menu item. It works.
The main window is linked to my ViewController class by default. The second window is also linked to the ViewController class and has its button linked to an IBAction in the ViewController class.
I have some simple code in the IBAction that basically tells the NSTextView to change its font size to a much bigger font. I have confirmed that the code itself works when called in other methods.
The button works, BUT it is using an entirely different instance of my ViewController class. So in result: the text size doesn't change.
So my main question here is how do I get an IBAction in one window to affect an object in another window.
I hope I did an alright job at explaining myself. Keep in mind this is my first Stack Overflow question:) I tried my best to research this question but mostly found information on iOS development and using XIB files.
It sounds like you have two windows with the same controller class but want what happens in one window to affect the other window. The easiest way is going to be with notifications. When the button is clicked in one window a notification gets posted that all instances of ViewController receive and respond to by changing the font size as needed. You could also look into setting a user default when the button is clicked and using bindings to keep the text field's font size tied to the current default.

Not loading the window from the MainMenu.xib, instead load another window

This is my first Mac OS-X app, so this might be a stupid question.
In my app basically i have two windows,
The Main window which comes with MainMenu.xib file by default
I created another WindowController with another xib file.
I have created a AppController class which is connected to the MainMenu.xib, what i am trying to do in the awakeFromNib method in the AppController class is load either the main Window or the custom window, but load the Main Menu each time. Is it possible?
I couldn't do it the previous way, if i needed to use the custom window, i would first create the main window and close it immediately.
I tried to get the main window by this, [[NSApplication sharedApplication]mainWindow]; and then closing it. But was unsuccessful.
I dont think i have proper understanding yet with windows, views and controllers of cocoa. i am following aaron hillegass's COCOA Programming for Mac OS X book.
please suggest me some other tutorials so that i can understand this thing clearly.
You need to un-check the windows "Visible at Launch"
Then based on your BOOL value, you need to show the window and make it orderFront.

Xcode: how to reset. No longer able to create outlet for newly added control in XIB

I have several XIBs following this pattern: a View Controller subclass containing a View subclass. I put my controls on that view.
Just now, I tried to add a new control to the view. I can do this, but I'm unable to connect the new control to an outlet. The assistant editor won't display the view subclass header either, though it will for a short while if I restart Xcode. Some other XIBs I have don't have the view controller object but instead have File's Owner set to a view controller subclass. They show the same problem.
Here is the Objects bar in IB:
"Matrix Editor View Controller" is a UIViewController subclass. This shows up fine in the Assistant Editor's "Counterparts" menu and I can drag from UIControls to it to create outlets & actions.
"Popup Cell View" is a UIView subclass. This is where the majority of my outlets and actions live. Previously this would show up in the Assistant Editor "Counterparts" menu and I could drag between it and my controls and the code quite happily. Now, whenever I add a new control in to this view, I can't drag from the Popup Cell View object to the new control, nor can I drag from the new control to the Assistant Editor window if it's showing the Popup Cell View header.
I recently had to upgrade to Lion (and hence Xcode 4.2.1 build 4D502); the last time I added controls to my XIBs was under Snow Leopard with the latest Xcode on that OS.
I believe that Xcode's caches or some internal state are out of whack. I have tried:
Restarting Xcode
A clean
Removing and re-adding the view subclass from the project
Deleting the DerivedData folder's contents from ~/Library/Developer/Xcode
And various combinations thereof. What else can I do to force Xcode to re-scan everything and allow me to connect up my controls to outlets?
Edit: I have noticed that I can create outlets in the View Controller for my new controls; I'm just not able to do this on the View subclass itself which is where I want them. I already have many on there. Could my new version of Xcode really be telling me that I'm not allowed to do this? Surely not. The Assistant Editor's Automatic mode changes every minute or so between two counterparts (the VC .h and .m) and four (the VC .h/.m and the View .h/.m).
Edit: I was able to connect an outlet, but only via this convoluted method:
Force the assistant editor to open my View subclass
Manually typing in an outlet for my new control
Dragging from the outlet in the assistant editor to the control itself
So something is very clearly broken. How can I fix it?
Very frustrating!
Thanks
When I have this problem, it is usually due to a mismatch in the class type somewhere. Verify that the class name of the object in you xib matched the class name in the interface and the implemetation files.
I'm a newb - I recognize this is a kludge, but hope this helps somebody. Sounds kinda sorta like the problem described above.
Suddenly, xcode refused to "insert new action outlets" into my AppDelegate.m (using control+drag, from a newly added xib element, into the class #implementation). Also, Xcode does not display that little-dark-circle next to each IBAction method in the .m file, like it used to.
Xcode allows drag of the blue-line from the 'source xib element' -- but would not show the "Insert Outlet or Action" & blue-circle-line with destination-highlight at the 'target line of insertion', in the .m file.
However, I can insert new outlet into my AppDelegate.h, using that above-described blue-line drag-method. That file is adorned with the cute little-black-circles, properly.
The kludge-around I came to was this
add 'bogus #implementation code' to the AppDelegate.h, as per:
#if 1
#implementation AppDelegate
#end
#endif
control+drag from the new xib element into/inside that #if 1 #implementation region in the .h
viola! xcode now displays the desired "Insert Action" & blue-circle-line target at the position for insertion. I can assign the method name and express whatever semantics I wish. Xcode source-editor shows a cute little-dark-circle to the left of the 'autogenerated' -(IBAction) line. For example, I added imanewxibobject as per:
#if 1
#implementation AppDelegate
- (IBAction)imanewxibobject:(id)sender {
printf("%s: hi there!\n",\_\_FUNCTION\_\_);
}
#end
#endif
(1+2)=3. Copy & paste that -(IBAction)imanewxibobject:... function into my actual AppDelegate.m (where it really belongs).
(2+2)=4. Turn that #if 1 (in the AppDelegate.h) to #if 0
(3+2)=5. recompile. Kablammo, the new UI element is alive with semantics!
I tried all: cleaning the project, deleting the files from the project, etc.
I peered into that .xib file and found it contained lots of what appears to be cross-referenced identifier indices, kinda what you may expect to see, in a file of this sort.
So I still don't have those little-dark-circles beside my -(IBAction)s -- but at least the code compiles, and I see the correct method-label string, for the Xcode Utilities->"Show Connections Inspector", with respect to the new UI element.
Anybody know how I can restore those cute little-dark-circles beside my "-(IBAction)"s? I find them very cute, and wish to have them back. I don't see any "Display cute-little-dark-circles" menu options. Bummer. Maybe in the next Xcode?

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.