- Published
- 23 August 2013
- Tagged
Update: I've since published a better way to do this whole thing. So give this article a read-through if you want, but check the link once you're done here.
While tricky to explain, this sort of thing is all over the place in Cocoa applications:
You have a tabbed view that takes up the entire main window, controller by a toolbar with a series of icons. This sort of thing is so common in Cocoa applications that it's probably more common than the actual NSTabView
:
When I wanted to split up my preferences window in Assign, I found myself wanting to make one of these tabbed views. Strangely enough, this sort of thing isn't default.
It's actually pretty easy - just not immediately obvious.
Setting up the .nib
This bit is pretty easy: add an NSToolbar
to the window to start, and put whatever icons you want in it. I tend to make mine non-customisable, since the user shouldn't be screwing around with adding/subtracting icons from this toolbar:
Now add an NSTabView
to the window. Change the style of the NSTabView so no tabs are visible up the top, and make the thing take up the whole window:
Make sure you have one subview per icon in your toolbar.
Writing the code
Now all we need is one controlling method to programmatically change the selected subview when the toolbar is clicked:
-(IBAction)toolbarButtonClicked:(id)sender {
[tabView selectTabViewItemWithIdentifier:[sender itemIdentifier]];
}
That was relatively painless! It works by a little bit of magic which involves having matching identifiers for your toolbars and tab views. When you select a toolbar item in Xcode, you'll see that it has an "identifier" field:
Each of these should be a unique number. You get a similar identifier field for NSTabbedView
subviews:
As long as the toolbar item matches up to a subview, you get incredibly easy switching.
Linking up
The only thing you need to do now is link up every NSToolbarItem
's selector
to the appropriate method in the nib
's controller. Since the NSToolbar
itself doesn't have a selector
property, you do have to link up each item.