给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:

 

 
  
  1. @interface NSIconTextCellValueObject : NSObject 
  2. <NSCopying> 
  3.  
  4. @property (copy) NSString * textValue; 
  5. @property (retain) NSImage * p_w_picpathValue; 
  6.  
  7. @end 
  8.  
  9. @implementation NSIconTextCellValueObject 
  10.  
  11. @synthesize textValue = _textValue; 
  12. @synthesize p_w_picpathValue = _p_w_picpathValue; 
  13.  
  14. -(id)copyWithZone:(NSZone *)zone 
  15.     NSIconTextCellValueObject* valueObject = [[NSIconTextCellValueObject alloc]init]; 
  16.     valueObject.textValue = self.textValue; 
  17.     valueObject.p_w_picpathValue = self.p_w_picpathValue; 
  18.     return valueObject; 
  19.  
  20. -(void)dealloc 
  21.     self.textValue = nil; 
  22.     self.p_w_picpathValue = nil; 
  23.  
  24. @end 

在NSTextFieldView的子类里实现重构objectValue:

 

 
  
  1. -(void)setObjectValue:(id<NSCopying>)obj 
  2.     NSIconTextCellValueObject * value = (NSIconTextCellValueObject*)obj; 
  3.     self.icon = value.p_w_picpathValue; 
  4.     [super setObjectValue:value.textValue]; 
  5.  
  6. -(id)objectValue 
  7.     NSIconTextCellValueObject * value = [[[NSIconTextCellValueObject alloc] init] autorelease]; 
  8.     value.textValue = [super objectValue]; 
  9.     value.p_w_picpathValue = self.icon; 
  10.     return value; 

这样,原先的textField部分就可以像父类一样显示。

顺便一提的是:一个OutlineView刷新的话实际是重用的一个cell,所以这个cell是必须得实现NSCopying协议的。

 
  
  1. -(id)copyWithZone:(NSZone *)zone 
  2.     NSIconTextCell * cell = (NSIconTextCell*)[super copyWithZone:zone]; 
  3.     cell.icon = [self.icon retain]; 
  4.     return cell; 

最后,再看看DataSource里怎么构造的objectValue,这个objectValue会自动传入到cell里。我这里只是用xml作测试的。这样理解起来应该很简单了。

 

 
  
  1. -(id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item 
  2.     NSIconTextCellValueObject * valueObject = [[[NSIconTextCellValueObject alloc] init] autorelease]; 
  3.     NSXMLElement * ele = (NSXMLElement*)item; 
  4.     if ([ele childAtIndex:0].childCount > 1)  
  5.     { 
  6.         valueObject.p_w_picpathValue = self.folderImage; 
  7.     } 
  8.     else 
  9.     { 
  10.         valueObject.p_w_picpathValue = self.fileImage; 
  11.     } 
  12.     valueObject.textValue = ele.name; 
  13.     return valueObject; 

没有提供源代码,主要是因为官方已经有样例代码了,我在这里修改了它的代码,主要是修改了objectValue这一块。以理解objectValue的来龙去脉。以便更好的使用它。