CocoaDev

Edit AllPages


Anyone know how to set NSTableView (or its delegate) up so that I can flip checkboxes in one of its columns without the row that the checkbox sits in becoming selected? The delegate implements tableView:shouldSelectRow: but it doesn’t tell me which column I’m clicking - for clicks in other columns selection should work normally. –GrahamCox


Stupid question first: does tableView:shouldSelectRow: or tableView:setObjectValue:forTableColumn:row: get called first? If it’s setObject…, you can just remember to ignore the next selection. –JediKnil


shouldSelectRow; gets called before     setObjectValue: unfortunately. Also, in the case where the row is already selected,     shouldSelectRow: isn't called at all, though for my purposes that doesn't matter. However, if you were to set a flag on one method and clear it on the other, you wouldn't always get the call to clear it, leaving it the wrong state. Sigh. All for the lack of passing the column to     shouldSelectRow:. --GC

It’s looking like it can’t be done. If I refuse the selection, the checkbox doesn’t get flipped anyway, so selectively refusing the selection according to column doesn’t help. That’s pretty annoying, as using a table in this way is not that unusual. There are plenty of times when you might want to flip a flag in an object that is in the table but not selected - think about turning off the visibility of layers in a stack for example. Looks like I might have to subclass the table, or maybe do something skanky in the cell. –GC


OK, I have a solution that works for my requirements, though may not be completely general. It requires subclassing both the table and the button cell, which is a lot of work for the stated need here in my opinion, but as far as have been able to tell, it’s the only way. Basically you need to override the mouseDown: for the table as a whole so that you can get the click before it selects anything - it seems as if selecting the row is the very first thing the table view does. The next problem is that having intercepted the click at this point, the standard tracking call to the button cell doesn’t work quite how I expect it to - I don’t get any visual feedback. So I ended up overriding this as well. This is probably not needed, but I couldn’t find out the magic sequence needed - maybe someone with more knowledge of the internals of table views and cells can figure it. Anyhoo, here’s the code:

@implementation GCTableView

@end

@implementation [[GCCheckboxCell

@end

I hope this will help someone avoid spending the 6 hours I just wasted on this. It really should be easier :( –GC


Gosh I’m having the same type of issue with trying to prevent selection changes while editing a table cell, and while I have a similar work around, it’d be really nice to have a better solution. – Hans Hansen


This isn’t exactly what you are trying to do, but it may help find a solution. I was trying to allow checkboxes in a table view to be checked without any row selection at all. In other words, I wanted the table view to behave as a list of check boxes, and never have a selection.

After lots of fiddling, I found that I could just implement one delegate method, and get the desired behavior:

-(void)tableViewSelectionIsChanging:(NSNotification *)aNotification { // Prevent row selection aNotification object] deselectAll:self]; }

This may help with the other cases above too — I’m not sure.

– [[DrewMcCormack


Problem is that will stop the table working in other cases where you want a selection, just not when you click a checkbox. In Leopard there is:

which addresses this - for Tiger you’re stuck with a hack (mine or someone else’s). -GC


Concerning the clicked column in tableView:shouldSelectRow:, you can also find it out via aTableView window] currentEvent] by checking if it is indeed a mouse event (also key events like cursor up/down may move the selection) and then calling columnAtPoint: with the converted locationInWindow. I’ve only tried it with an [[NSOutlineView, but it should also be working with the superclass NSTableView.

Of course you need (at least) Leopard, as pointed out above, ‘cause former system versions do not allow clicking without selecting.

–G.Pfister