Posts tagged ‘Interface Builder’

Safari like button bar in Interface Builder

In the previous post on the use of NSGradient I showed a screenshot of a button bar similar to the one that is used in Safari to store your favourites. For an application I’m writing I have an NSTableView with date based rows, and I want to allow easy filtering the table contents on date ranges like month, last month, week, last week etcetera. A button bar is nice looking way of doing this, the screenshot below shows what this looks like (in Dutch, but you’ll get the idea).


Until recently you had to use for example AMButtonBar to get a button bar like this, but with Leopard our developers life has again been made easier: you can now create the button bar in Interface Builder, using only standard components.

Start by dropping an NSMatrix component (you will find this in the objects library under Views & Cells, Inputs & Values) onto your view. Per default it creates a matrix of 1 column, 2 rows with radio buttons on it. Then set the correct prototype on the NSMatrix object so that newly added buttons will have look right. Click on the little circle that is visible on the right bottom of the NSMatrix when it’s selected,



then the prototype attributes are shown in the Inspector window. Select Recessed as Style, and use centered Alignment. Select the right value under Position, based on whether you want to add an image to the buttons or not. In this case I choose not to use images.



Once the prototype is setup properly, select the NSMatrix object and have a look at the attributes in the Inspector window.



Change the number of rows and columns to meet your needs, in this case I’m using 1 row and 6 columns. You end up with one traditional radio button (the one that was originally there) and 5 new buttons according to the prototype. Select the first button and manually set its properties so that it matches the prototype as well.

Next, for each button edit the button Title and specify a unique Tag value in the Inspector window, so that you can distinguish which button was clicked in the attached method in your code later on. Optionally you can add a tooltip under the Identity tab on the Inspector window.

The final step is to write the method in the controller class, and attach it to the NSMatrix object. When you use the tag values to identify which button was clicked you will only need a single method, and don’t have to attach a method directly to the buttons. A sample implementation method:


- (IBAction)filterData:(id)sender
{
    int tag = [sender selectedTag];

    switch (tag) {
        case 1000: // Show all
            // Remove data  filtering so that all rows are shown
            break;
        case 1001: // Show this month
            // Filter data so that only rows with a date between
            // first and last day of current month are shown
            break;
        case 1002: // Show last month
            // Filter data so that only rows with a date between
            // first and last day of previous month are shown
            break;
        default:
            // Should never get here
            break;
    }
}

If you’re using coredata filtering the data is very easy, as you only need to create a NSPredicate object in which you specify the filtering criteria, and set that predicate on the NSArrayController that holds the rows. This is beyond the scope of this post, if you have questions on that let me know.

Build a toolbar in Interface Builder

Interface Builder 3 (IB3), part of the development tools that are shipped with Mac OS X Leopard, finally allows building an application window toolbar. Until the release of IB3 the setup had to be done entirely in code, or through a 3rd party extension to IB. Allthough the toolbar in the application I’m working on was working fine, I couldn’t resist the temptation to move its definition into my NIB file and clean up my code a bit.

In the objects library, under Application there is a new set of objects filed as Toolbar. You can drop a toolbar object onto a window which will give you a standard implementation of the toolbar, with icons for Show colors, Show fonts, Print and Customize. Select the toolbar to change its default properties in the Attribute Inspector window. Note that a new toolbar has the Customizable checkbox unchecked, meaning that a user of you application can’t customize the toolbar. Simply check it to change this behaviour.

To change the toolbar, you need to click on it in the window where you dropped it, which shows a panel containing the allowed toolbar items.

From the object library you can add toolbar items, either one of the standard items or an image item. Alternatively you can drop an image directly from the media library which will create an image item. On the Attribute Inspector window you can change the attributes for an image toolbar item (on Toolbar Item Attributes), and add a Tooltip (on Toolbar Item Identity). To change the standard toolbar that will be active when the application is started, drag items from the panel onto the toolbar, or drag items you don’t want out of the toolbar.

The standard items will have default activities attached to them, for the image items you added yourself you will have to add an action by Control-dragging from the item to an object (usually FirstResponder or File’s Owner) and selecting the action you want executed when the item is clicked.

This is all really easy, as long as you keep in mind that attributes and actions are specified on the items in the panel with the allowed items, rather on the items in the toolbar itself. While most of the configuration can now be done in IB, you still need to implement the method:

- (BOOL)validateToolbarItem:(NSToolbarItem *)theItem

in the class that is the delegate for the toolbar. In the implementation of the method you need to check for which item it was called, and return YES or NO depending on whether you want the item to be active (clickable) or not. You set tag values for the different items in IB against which you can check for which item the validateToolbarItem method is called. A sample implementation for a save button in a document based application could look like this:

- (BOOL)validateToolbarItem:(NSToolbarItem *)theItem
{
    if ([theItem tag] == 1001) // Save toolbar item
        return [self isDocumentEdited];
    return YES;
}

One thing to note: if you have put a toolbar into your NIB file, you will need to save the file in either XIB3.x or NIB3.x format. Saving in NIB2.x format is not supported, so you lose backwards compatibility with IB2.