You don’t need to post the code for me; I’m the one who wrote it over at Stackoverflow, so I have a copy of it.
Simplest things first. To keep the table from selecting every row on insert, un-click ‘Select inserted objects’ in the Attributes Inspector of the Array Controller object. And don’t worry about selecting a row programmatically. whenever the selection changes, regardless of how or why it changes (with a few minor exceptions), the tableview will call its delegate and function properly. On a certain level you have to trust that things will work; avoid worrying until you see an actual problem.
With respect to visual aesthetics… First, in the table view’s Attributes Inspector, you might want to change the highlight option to SourceList. It’s a smoother look, but it’s more difficult to adjust programmatically. (Sorry, I’m not sure how to post images here, or I’d show you)
There are two kinds of view you see in a table view: Table Cell Views (NSTableCellView) and Table Row Views (NSTableRowView). Cell views are the normal views used to display table cells in columns; row views are views used to display groups rows (like the headers used in this sidebar). You have to at least one cell view defined in the nib, but the table view will define a default row view for you (which is what you’re seeing currently). You can, of course, create as many cell and row views as you like and call them programmatically (by identifier) for different contexts.
These delegate methods allow you to assign (or even programmatically create) row and cell views for specific data items:
on tableView:tableView viewForTableColumn:tableColumn row:row
--
end
on tableView:tableView rowViewForRow:row
--
end
… while these delegate methods allow you to catch a cell or row before display and modify some of its visual aspects:
on tableView:tableView willDisplayCell:cell forTableColumn:tableColumn row:row
--
end
on tableView:tableView didAddRowView:rowView forRow:row
--
end
You might also find this method useful, which lets you set row heights individually:
on tableView:tableView heightOfRow:row
--
end
As far as specific implementations go, I’ll throw out two options:
Option 1
This is easiest, and only involves going to the Table View’s Attributes inspector in the xib and changing the Highlight option to Source List. Source lists have a smoother look which you might like out of the box, but it is hard to change header items (I think it’s possible, but I’d have to play with it a bit). For instance, if you add this method:
on tableView:tableView didAddRowView:rowView forRow:row
set rowCell to rowView's subviews's objectAtIndex:0
set rowTextField to rowCell's textField
rowTextField's setTextColor:(current application's NSColor's greenColor)
end
it will change all of the regular lines to green, but not the headers.
Option 2
This involves forgetting about using grouping rows (which aren’t really necessary anyway since this is a simple, flat source list). Keep the Table View’s Highlight option at Regular, delete the entire ‘tableView:isGroupRow:’ method, and then pull a second Table Cell View out of the object library and add it to the table column. Give that one the identifier (say) ‘headerItem’, and rewrite the ‘tableView:viewForTableColumn:row:’ method like so:
on tableView:tableView viewForTableColumn:column row:row
-- header rows get a special look
set rowData to arrayController's arrangedObjects's objectAtIndex:row
if rowData's isHeader as boolean is false then
set aView to tableView's makeViewWithIdentifier:"tableItem" owner:me
else
set aView to tableView's makeViewWithIdentifier:"headerItem" owner:me
end
return aView
end
Then style the two Table Cell Views in IB to get the look you want for the headers and rows. This method will now call a different view for headers and regular items.