How to override NSWindow? - objective-c

I need to create a custom window, so I have created a subclass of NSWindow. I overode the constructor and a bunch of other functions.
I need to replace the current window with the window subclass I created. I know it has something to do with Interface Builder but have no idea what to do. How would I do this?
I tried removing the NSWindow from the Inspector, and instead adding my custom window, however this only results in no window showing up during runtime.
I also edited the app's delegate to change NSWindow to my custom window and also changed the delegate's "main" outlet to my custom window.
I am on Mac OSX Snowleopard using Xcode 3.2.6

First, you need to make sure Interface Builder knows about your custom class. To do this, open your xib file and go to "File->Read Class Files…", and choose your header file.
Then, select the window you want to change and open the inspector. In the last tab of the inspector, under "Class Identity", there is a text field labeled "Class" simply type your class's name here.
After you do this, your custom class will be used as the class for that window. It will look like a normal window in IB, but will let you use custom outlets and actions, and will use your class when you actually run your project.

go to the third tab of the utilities section when your window is selected
enter your custom class name under 'Custom Class'

Related

Adding a new window in Cocoa

I'm a beginner with Cocoa programming. All I wnated to know is how do I create a new window in Cocoa. I have created a NSViewController and window. As shown in tutorials I was able to add buttons to the MainMenu window and add actions to the buttons. Now I added a new NSViewController. I then went to plist file and made to load it first. My questions are as follows.
When adding a new NSViewController, h m and xib files were created but the XIB file just has custom window and no other control elements like minimize max buttons etc.
Secondly I added few elements and ran the file. The application ran but nothing was displayed on screen. Am I missing something.
You mostly only create a new NSWindowController if you add a new Nib-File.
The advantage of separating your windows or separate views in Nib-Files can be:
Making your code more organized
Easy instantiation of multiple windows of the same type (like browser windows)
If you don't need this, you can simply add a new window to your MainMenu.xib.
Then you can either let the window be visible at launch, or make an outlet to it and make it visible whenever you desire.
Otherwise you can go to your files -> Add new file -> Subclass of NSWindowController
There will be a checkbox to automatically create the xib-file for you, make sure to check.
Now just make sure to initialise with initWithWindowNibName:, and call showWindow: on it.
MyWindowControllerSubclass *wcs = [[MyWindowControllerSubclass alloc] initWithWindowNibName:#"TheNameOfMyNib"];
[wcs showWindow:self];
I was using XCode 4.2. Now I updated to 4.6.3. Now while creating NSWindowController xib file creating option is there. SO its done directly.
Otherwise you need to add a window controller and a new Window XIB. Later you can add an Object to properties tab. Then change the class to the Window Controller and link the Window to the Object.
If you want to add the view controller to a window then, it is fairly simple. NSViewController has a property named view. You would add this view to the window.contentView.
You would typically create a new xib file with a view and setting the file owner to your view controller. Then in the -(id)initWithNibName: method you could call the super with the nib name of your view to instantiate the controller with its view.
If you want to show a new window. Then create a new NSWindowController object and instantiate it, with the nib of your window and calling window on the controller should bring the window to front. If your window has already been initialised then, you could call methods like orderFront:, orderBack: on the window of the controller.

Drag custom view onto window in Interface Builder?

I'm coming from the world of C# and Winforms where I can build a custom UserControl and drag it onto a form as if it were a common control. Is there a way to do that in Xcode and Interface Builder?
I've only seen how to set the view at runtime but I'd like to see it on my window at design time. For example, I'd expect my custom view to be listed in the available controls.
Thanks!
Simon
Interface Builder doesn't add (or allow the addition of, now that IB Plugins are derelict) Custom Objects to the Object Library. You can only drag in existing/preset objects, but you can have IB instantiate them as instances of a subclass as long as they are instantiated the same way.
E.g. Drag in a custom view and set the class to MyCustomViewClass, or drag in a scroll view and set the class to MyCustomScrollView, or drag in an object and set the class to CustomObject, et cetera.
And that is the preferred way of using custom controls in Interface Builder.
Basically just ripping off rdelmar's comment... but I thought a picture would be helpful
Drag a normal view into IB, then select it and do this.
Every Window you create in IB has a view on it as its first subcomponent. You dont need to create a separate custom view for it. If you really are subclassing it just change the class name in the inspector.
In addition to what has been mentioned in this thread about adding your custom view's name to the view controller's XIB file, you will need to override initWithCoder in your custom view.

Configure the window of an NSWindowController before it appears on screen

I am using an NSWindowController not I want to set some attributes (specifically the styleMask property) on the window, before the actual window is shown. However, the window property on the NSWindowController is only available once the window is already on screen.
I could use initWithWindow: on the NSWindowController but then I am no longer able to use a nib file for the content of the window (because this uses initWithWindowNibName:.
So how can I configure the view before it is shown, something similar to viewWillAppear on NSView?
In Interface Builder, uncheck the ‘Visible At Launch’ attribute. When doing this, the window is not shown when the corresponding nib file is loaded by the window controller, so you can configure your window in -[NSWindowController windowDidLoad] and then manually show it using -[NSWindowController showWindow:].
Note that there’s no -viewWillAppear method in Cocoa.

How can I make sure a window is only displayed once in Cocoa?

I have an NSWindow which contains an NSImageView. This window gets activated everytime I click on a cell in my tableview. I only want 1 instance of the NSWindow to appear, but want to be able to change the contents of NSImageView.
How can I initialize NSWindow and display only 1 instance of it?
This is a job for a singleton!
http://developer.apple.com/documentation/Cocoa/Conceptual/CocoaFundamentals/CocoaObjects/CocoaObjects.html#//apple_ref/doc/uid/TP40002974-CH4-SW32
One possibility to do this is to create an NSWindowController subclass and an associated window XIB that gets loaded when the window controller is instantiated.
I'm sure you already have some controller class handling the mouse click in the NSTableView. In that class, simply keep around an instance of the NSWindowController subclass mentioned above as an instance variable. Whenever you need to display the window, tell that ivar to display its window.
If the window's contents are dependent on the clicked table cell, simply add some methods to the window controller that modify its window's contents and call these methods in your click-handling method before you display the window.
btw: I wouldn't use a singleton here because in this case it would just be a workaround for bad design (just my opinion, not a hard fact).

Creating Cocoa PopUpMenus programmatically and Getting code form a GUI item built with the interface builder

I need to create many Cocoa items programmatically and most resources I can find focus on creating GUI with the builder. Is there any way to get the objective C code for an interface item created using the interface builder in Xcode? Also, I am a little confused about PopUpMenus. Are PopUpMenus contained inside PopUpButtons or are the independent? Also, can anyone link me to a good description of how to create PopUpMenus programmatically Using Cocoa and Objective-C?
It depends on what you mean by "PopUpMenus". In Cocoa a menu is a menu, specifically an instance of NSMenu. NSPopupButtons have an associated NSMenu object which you can assign to the button using the -setMenu: method.
You can certainly construct menus programmatically using the NSMenu and NSMenuItem classes. Take a look at the various -addMenuItem: methods in the NSMenu documentation.
You can also access the components of a menu created in Interface Builder programmatically if you have a reference to the menu, specifically an outlet instance variable that is connected to the menu in Interface Builder.
If you're referring to contextual menus that appear when you click the right mouse button, all you need to do is connect your menu to the view/control you want to attach it to with the -setMenu: method. You can make this connection in Interface Builder also.