featured software



wordmake



pianopub



recipe manager

HowTo: Disappearing NSTable Buttons

Posted: August 10th, 2010 | Author: | Filed under: Cocoa, OS X, Programming | No Comments »
Disappearing NSTable Buttons

Completed Project

Recently I was working on a project where I wanted a certain effect. This was that I wanted the user to be able to delete items out of a table by clicking on the item and not having to add some button somewhere else to do it. So the answer was to put a button on the table to delete it. That was simple enough, just make a table with button cells, but it didn’t look very nice, it showed all the button when you could only delete one at a time. So thus, I decided to make the buttons only appear on the selected table items. Its simple, functional, and you can do it too if you just follow this short guide.

To tackle this problem, there are two “hacks” that we need to do.  First, we have to somehow make the NSButtonCell hide itself.  Next, we have to keep track of which row is selected, and tie that information back to our buttons. To accomplish the first task, will tie the button being hidden to it’s enabled value, since this way is easier then creating a new binding, and it doesn’t matter is the button is disabled if it’s hidden anyway.  Subclass NSButtonCell and override this method with this code.

- (void) drawWithFrame: (NSRect)cellFrame inView: (NSView*)controlView
{
	if([self isEnabled])
		[super drawWithFrame:cellFrame inView:controlView];
}

In interface builder, drag a NSButtonCell to one of the columns of your NSTableView. (Apple hides it as a ‘Check Box Cell’, see below, you have to change the type to ‘Momentary Push In’).

Interface Builder Check Box Cell (NSButonCell)

Check Box Cell (NSButtonCell)

Setting the Class to HidingButtonCell

Setting the Class to HidingButtonCell

Change the class to your custom subclass. Next we need to somehow get the data in a form we can bind to the button’s enabled key.  There are potentially a couple ways to do this, but I decided to subclass NSTableView, and override this method.

- (void)selectRowIndexes:(NSIndexSet *)indexes byExtendingSelection:(BOOL)extend
{
	[super selectRowIndexes:indexes byExtendingSelection:extend];
	[controller setSelectionIndex:[indexes firstIndex]];
 
	int i;
	for(i = 0; i < [[controller arrangedObjects] count]; i++)
	{
		[[[controller arrangedObjects] objectAtIndex:i] setObject:
			[NSNumber numberWithInt:[indexes firstIndex] == i] forKey:@"enabled"];
	}
 
}

Of, course this way of doing this assumes you’re binding to an NSArray of NSMutableDictionaries.  Next, back in Interface Builder we can bind the column to the new data that’s going to be generated with that method. And thats it enjoy you’re disappearing buttons.  If you want the button to delete the row, like mine, just connect the NSButtonCell’s action to the NSArrayController’s remove: method. If I made any mistakes, or made anything unclear, please leave a comment.  For a closer look, Download the Xcode Project



Leave a Reply