给OutlineView的条目添加图标
给OutlineView添加图标,图片其实是一个自定义NSTextFieldCell的过程。
在OutlineView里每一个item都有一个Item数据结构,一个item对应一个cell,这个数据结构仅仅与一个item关联,是无法显示的。我们可以根据这个数据结构来传给 cell一个objectValue,这个objectValue由OutlineViewDataSource传递到cell里,作为cell的一个数据成员。
通常情况下一个cell是一个NSTextField实例。它的objectValue是一个NSString.自定义一个cell当然也是可以用原先的objectValue,因为我们需要根据这个objectValue来重绘这个cell所以我们一般会重新构造这个objectValue.
关键代码如下:
定义ObjectValue:
- @interface NSIconTextCellValueObject : NSObject
- <NSCopying>
- @property (copy) NSString * textValue;
- @property (retain) NSImage * imageValue;
- @end
- @implementation NSIconTextCellValueObject
- @synthesize textValue = _textValue;
- @synthesize imageValue = _imageValue;
- -(id)copyWithZone:(NSZone *)zone
- {
- NSIconTextCellValueObject* valueObject = [[NSIconTextCellValueObject alloc]init];
- valueObject.textValue = self.textValue;
- valueObject.imageValue = self.imageValue;
- return valueObject;
- }
- -(void)dealloc
- {
- self.textValue = nil;
- self.imageValue = nil;
- }
- @end
在NSTextFieldView的子类里实现重构objectValue:
- -(void)setObjectValue:(id<NSCopying>)obj
- {
- NSIconTextCellValueObject * value = (NSIconTextCellValueObject*)obj;
- self.icon = value.imageValue;
- [super setObjectValue:value.textValue];
- }
- -(id)objectValue
- {
- NSIconTextCellValueObject * value = [[[NSIconTextCellValueObject alloc] init] autorelease];
- value.textValue = [super objectValue];
- value.imageValue = self.icon;
- return value;
- }
这样,原先的textField部分就可以像父类一样显示。
顺便一提的是:一个OutlineView刷新的话实际是重用的一个cell,所以这个cell是必须得实现NSCopying协议的。
- -(id)copyWithZone:(NSZone *)zone
- {
- NSIconTextCell * cell = (NSIconTextCell*)[super copyWithZone:zone];
- cell.icon = [self.icon retain];
- return cell;
- }
最后,再看看DataSource里怎么构造的objectValue,这个objectValue会自动传入到cell里。我这里只是用xml作测试的。这样理解起来应该很简单了。
- -(id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item
- {
- NSIconTextCellValueObject * valueObject = [[[NSIconTextCellValueObject alloc] init] autorelease];
- NSXMLElement * ele = (NSXMLElement*)item;
- if ([ele childAtIndex:0].childCount > 1)
- {
- valueObject.imageValue = self.folderImage;
- }
- else
- {
- valueObject.imageValue = self.fileImage;
- }
- valueObject.textValue = ele.name;
- return valueObject;
- }
没有提供源代码,主要是因为官方已经有样例代码了,我在这里修改了它的代码,主要是修改了objectValue这一块。以理解objectValue的来龙去脉。以便更好的使用它。