views:

87

answers:

1

I would like to display an icon next to a text item in an single cell of a table view.

An example of what I want to achieve is the application list in System Preferences -> User Accounts -> Login Items.

What's a good way?

+1  A: 

There is a good example here how to do it: http://www.cocoadev.com/index.pl?IconAndTextInTableCell You make your own custom NSCell that both draws a image and text

@interface IconCell : NSCell 
{
NSArray * cellValue;
}
- (void)setObjectValue:(id <NSCopying>)object;
- (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView;

@implementation IconCell

- (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView
{
NSDictionary * textAttributes =
    [NSDictionary dictionaryWithObjectsAndKeys:[NSFont 
userFontOfSize:10.0],NSFontAttributeName, nil];
NSPoint cellPoint = cellFrame.origin;

[controlView lockFocus];

[[cellValue objectAtIndex:1] compositeToPoint:NSMakePoint(cellPoint.x+2,
cellPoint.y+14) operation:NSCompositeSourceOver];
[[cellValue objectAtIndex:0] drawAtPoint:NSMakePoint(cellPoint.x+18,
cellPoint.y) withAttributes:textAttributes];

[controlView unlockFocus];
}

- (void)setObjectValue:(id <NSCopying>)object
{
   cellValue = (NSArray *)object;
}
@end
Jonas Jongejan
Worth pointing out that that cell requires the data source to serve up an array of (filename, icon) as the object value. Extra credit for the questioner: Adapt the cell code to expect an NSURL as the object value, and obtain both the filename and the icon from it.
Peter Hosey
Cool, good stuff. What I'm actually doing at the moment is binding my table view through an array controller to an array of bundle ids, via a value transformer which which converts the bundle id to application display name. I'm thinking my value transformer could put out the image and text combo for the cell to draw. Anyway I'll need to read up about NSCell now. Something I've not had to deal with before ...
invariant
Using -tableView:willDisplayCell: delegate method to set the image portion avoids the need to use an array as the object value. It can also be mixed freely with Bindings.
Joshua Nozzi