• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: While on the subject of: NSOutlineView
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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.

References: 
 >While on the subject of: NSOutlineView (From: April Gendill <email@hidden>)

  • Prev by Date: Linking a Menu To A Document
  • Next by Date: Re: While on the subject of: NSOutlineView
  • Previous by thread: While on the subject of: NSOutlineView
  • Next by thread: Cron Job Utility or GUI for Mac OS X?
  • Index(es):
    • Date
    • Thread