Re: While on the subject of: NSOutlineView
Re: While on the subject of: NSOutlineView
- Subject: Re: While on the subject of: NSOutlineView
- From: Chris Hanson <email@hidden>
- Date: Wed, 30 Jul 2003 15:07:37 -0500
April:
Table views and outline views don't store data. Rather, they just
enable user interaction with the data (viewing and editing). The
object that actually deals with the data is the table view's or outline
view's data source.
This data source can be an instance of any class; it doesn't need to
implement a particular protocol, or descend from a particular base
class. It only needs to respond to a few specific selectors in order
to work. The base set of selectors for a table view is
-numberOfRowsInTableView:, -tableView:objectValueForTableColumn:row:,
and (if your table view supports editing)
-tableView:setObjectValue:forTableColumn:row:.
Outline views are slightly more complicated because they're displaying
hierarchical data; outline views pass around opaque "item" tokens
instead of row index values. These item tokens can be objects of any
class; be aware, though, that you have to actually manage their
lifetime yourself. (This is a fancy way of saying NSOutlineView
doesn't retain its items.)
The standard trick is to use the "identifier" string associated with a
table column as a key-path into the model object that a row in your
table or an item in your outline view is representing. This lets you
easily set up a table in Interface Builder, and let some completely
generic code manage getting data between it and a data source like an
array of dictionaries. Your implementation of
-tableView:objectValueForTableColumn:row: can then look something like
this:
- (id)tableView:(NSTableView *)tableView
objectValueForTableColumn:(NSTableColumn *)column
row:(int)row
{
return [[someDataArray objectAtIndex:row]
valueForKeyPath:[column identifier]];
}
while your implementation of
-tableView:setObjectValue:forTableColumn:row: can then look something
like this:
- (void)tableView:(NSTableView *)tableView
setObjectValue:(id)value
forTableColumn:(NSTableColumn *)column
row:(int)row
{
[[someDataArray objectAtIndex:row] takeValue:value
forKeyPath:[column identifier]];
}
and of course your -numberOfRowsInTableView: will look like this:
- (int)numberOfRowsInTableView:(NSTableView *)tableView
{
return [someDataArray count];
}
Because I prefer to keep everything wrapped up into a completely
generic TableController object that acts as a table data source, and
uses a key path to query a data source of its own for an array of
objects to display. I even have an Interface Builder palette now that
I can use to set the key path for one of these, so I can set up simple
tables with no code.
If you want a simple code example of using table views, check out the
source code to my BDRuleEditor application. It's at
<
http://bdistributed.com/Projects/BDRuleEditor/>. I don't use the IB
palette, but I do use the same technique.
For table view drag and drop, there are a few additional data source
and delegate methods you should look at. Dragging within a table sends
its data source -tableView:writeRows:toPasteboard:, while dropping onto
a table sends its data source
-tableView:validateDrop:proposedRow:proposedDropOperation: while the
drag is going on and -tableView:acceptDrop:row:dropOperation: when the
drop occurs. To tell a table it should accept drops in the first
place, you send it -registerForDraggedTypes: just as you would for any
view that you wanted to accept drops.
It's analogous with outline views, only again instead of row indexes
you get item values. There's an added wrinkle because by displaying
hierarchical data, you may have objects of more than one type selected
(for instance, folders & files) so you have to be sure to distinguish
the types where doing so is important for your application. But that's
not too tough, especially with the type-introspection facilities in
both Objective-C and Java.
-- Chris
--
Chris Hanson, bDistributed.com, Inc. | Email: email@hidden
Custom Mac OS X Development | Phone: +1-847-372-3955
http://bdistributed.com/ | Fax: +1-847-589-3738
http://bdistributed.com/Articles/ | Personal Email: email@hidden
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.