基于cell-base的NSTableView

来源:互联网 发布:内存中存放的是数据 编辑:程序博客网 时间:2024/05/16 19:19

写此文章,一是积累一下知识,二也是因为某个项目要求在10.6上运行,但由于10.6的NSTableView只支持Cell-Base。因此想与iphone一样,把一些视图addsubview来说就要走点弯路了。在10.7下就可以完全使用view-base来实现。对于view来说,大家都用得很顺手了,想什么画什么,add一下就OK了,但基于cell-base 的row cell,你还使用addview吗?要想了解CELL 就得先了解一下NSCell,这个是Cell的祖宗了,在mac os中各个控件基本上都有一个cell,而这些cell都是从NSCell派生出来。如果不清楚建议先了解一下。

下面重点回到tableView上,讲一下在cell-base上碰到的问题,及解决方式,如果还有更好的,请高人指点。

question:

1.如何自定义绘制某列某行的表格显示自己想要的样式?

2.如何锁定指定的行不允行选中或修改?

3.如何当鼠标进入到指定的cell中进行触发事件?

4.如何实现NSTableView的动态高度?并随列的大小改变而自动设置高度?

5.如何更改选中的行的高亮色?

6.如何可以进行选择自定义cell中的文字进行选中操作?

7.如何实现Cell中的文字高亮部分显示?


NSTableView 的代码Create部分:

[objc] view plaincopy在CODE上查看代码片派生到我的代码片
  1. NSScrollView * tableContainer = [[NSScrollView alloc] initWithFrame:NSMakeRect(1010560540)];  
  2.     FSHighlightTableView * tableView = [[FSHighlightTableView alloc] initWithFrame:NSMakeRect(00544540)];  
  3.     // create tableview style  
  4.     //设置水平,坚直线  
  5.     [tableView setGridStyleMask:NSTableViewSolidVerticalGridLineMask | NSTableViewSolidHorizontalGridLineMask];  
  6.     //线条色  
  7.     [tableView setGridColor:[NSColor redColor]];  
  8.     //设置背景色  
  9.     [tableView setBackgroundColor:[NSColor greenColor]];  
  10.     //设置每个cell的换行模式,显不下时用...  
  11.     [[tableView cell]setLineBreakMode:NSLineBreakByTruncatingTail];  
  12.     [[tableView cell]setTruncatesLastVisibleLine:YES];  
  13.       
  14.     [tableView sizeLastColumnToFit];  
  15.     [tableView setColumnAutoresizingStyle:NSTableViewUniformColumnAutoresizingStyle];  
  16.       
  17.     //[tableView setAllowsTypeSelect:YES];  
  18.     //设置允许多选  
  19.     [tableView setAllowsMultipleSelection:NO];  
  20.       
  21.     [tableView setAllowsExpansionToolTips:YES];  
  22.     [tableView setAllowsEmptySelection:YES];  
  23.     [tableView setAllowsColumnSelection:YES];  
  24.     [tableView setAllowsColumnResizing:YES];  
  25.     [tableView setAllowsColumnReordering:YES];  
  26.     //双击  
  27.     [tableView setDoubleAction:@selector(ontableviewrowdoubleClicked:)];  
  28.     [tableView setAction:@selector(ontablerowclicked:)];  
  29.       
  30.     //选中高亮色模式  
  31.     //显示背景色  
  32.     [tableView setSelectionHighlightStyle:NSTableViewSelectionHighlightStyleRegular];  
  33.     //会把背景色去掉  
  34.     //[tableView setSelectionHighlightStyle:NSTableViewSelectionHighlightStyleSourceList];  
  35.     //NSTableViewSelectionHighlightStyleNone  
  36.       
  37.     //不需要列表头  
  38.     //[tableView setHeaderView:nil];  
  39.     //使用隐藏的效果会出现表头的高度  
  40.     //[tableView.headerView setHidden:YES];  
  41.       
  42.     // create columns for our table  
  43.     NSTableColumn * column1 = [[NSTableColumn alloc] initWithIdentifier:@"col1"];  
  44.     [column1.headerCell setTitle:@"第一列"];  
  45.     //[column1 setResizingMask:NSTableColumnAutoresizingMask];  
  46.       
  47.     NSTableColumn * column2 = [[NSTableColumn alloc] initWithIdentifier:@"col2"];  
  48.     [column2.headerCell setTitle:@"第二列"];  
  49.     //[column2 setResizingMask:NSTableColumnAutoresizingMask];  
  50.       
  51.     [column1 setWidth:250];  
  52.     [column2 setWidth:250];  
  53.       
  54.     // generally you want to add at least one column to the table view.  
  55.     [tableView addTableColumn:column1];  
  56.     [tableView addTableColumn:column2];  
  57.       
  58.     [tableView setDelegate:self];  
  59.     [tableView setDataSource:self];  
  60.       
  61.     // embed the table view in the scroll view, and add the scroll view to our window.  
  62.     [tableContainer setDocumentView:tableView];  
  63.     [tableContainer setHasVerticalScroller:YES];  
  64.     [tableContainer setHasHorizontalScroller:YES];  
  65.     [self addSubview:tableContainer];  
  66.     [tableContainer release];  
  67.     [tableView release];  
  68.     [column1 release];  
  69.     [column2 release];  

上述代码是创建一个二列的table(本人不太习G使用IB来弄UI)。

再来看一下代理。

关键的:

[objc] view plaincopy在CODE上查看代码片派生到我的代码片
  1. - (CGFloat)tableView:(NSTableView *)tableView heightOfRow:(NSInteger)row  
  2. {  
  3.   
  4.     NSTableColumn *column = [[tableView tableColumns] objectAtIndex:0];  
  5.     NSCell *dycell = [tableView preparedCellAtColumn:0 row:row];  
  6.     NSRect cellBounds = NSZeroRect;  
  7.     cellBounds.size.width = [column width]; cellBounds.size.height = FLT_MAX;  
  8.     NSSize cellSize = [dycell cellSizeForBounds:cellBounds];  
  9.     return cellSize.height;  
  10. }  
  11.   
  12. - (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView  
  13. {  
  14.     return listData.count;  
  15. }  
  16.   
  17. - (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row  
  18. {  
  19.     return [listData objectAtIndex:row];  
  20. }  
  21.   
  22. - (NSCell *)tableView:(NSTableView *)tableView dataCellForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row  
  23. {  
  24.     if ([tableColumn.identifier isEqualToString:@"col1"]) {  
  25.         FSDyHeightCell *dycell = [[[FSDyHeightCell alloc]init]autorelease];  
  26.   
  27.         dycell.display = [listData objectAtIndex:row];  
  28.         return dycell;  
  29.     } //一定要写判断条件,原来只有一个else 显示的不对,不写的话永远不会进第一列  
  30. //    else if ([tableColumn.identifier isEqualToString:@"col2"])  
  31. //    {  
  32. //        FSCell *customCell = [[[FSCell alloc]init]autorelease];  
  33. //          
  34. //        [customCell setSelectionBKColor:[NSColor lightGrayColor]];  
  35. //        [customCell setSelectionFontColor:[NSColor redColor]];  
  36. //        return customCell;  
  37. //    }  
  38.     return nil;  
  39. }  

看起来是不是有点像iphone的tableView呀。确实有点,不过mac的有列的概念了。其实这几个代理就可以基本的把数据显示出来。这没有什么好奇怪的。但要对每个cell进行一些功能的扩展或自定义,这就需要费时了。

问题1:先看一下未定义之前,NSTableView为我们默认创建了一个NSTextFieldCell的对象来进行显示数据,


很简单的数据显示,但往往我们有时需要在某个表格中有图,有字显然NSTextFieldCell是不够的了,可以参考一下官网提供的ImageAndTextCell 。另外我们也可以自己从NSCell派生下来,自己实现NSCell的

- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView;方法,使用这个方法draw时可以按照自己的想法把图,文等都可以draw上去,但这个就需要有点CGGraphics 的功底了。这个方法还有一点要注意的就是cellFrame 的y轴坐标,这个坐标是一个y轴的偏移坐标。因此在使用这个来draw东东时,rect的y轴一定要跟着变,否则你看到的只有一行数据,大家都积在同一坐标点上了,另外,这个y的值会把grid的线条宽加在内,比如每行之间线条是1,哪么在第10行的时候,中间隔了9条线,哪么第10行的y的偏移会是9行的高度+8行的线行宽度的值作为第10行的起始偏移点,这个大家体会一下吧,可能我描术的不是很清楚。


如图中,我自己将第二列进行自定义,当然这个大家可以按自己的需要进行绘制。贴下简单的码:

[objc] view plaincopy在CODE上查看代码片派生到我的代码片
  1. - (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView  
  2. {  
  3.     //选中高亮色这种只能改变某个Cell的背景色不能整行改变  
  4.     if ([self isHighlighted]) {  
  5.         [self highlightColorWithFrame:cellFrame inView:controlView];  
  6.     }  
  7.       
  8.     NSColor* primaryColor   = [self isHighlighted] ? [NSColor alternateSelectedControlTextColor] : [NSColor textColor];  
  9.       
  10.     NSDictionary* primaryTextAttributes = [NSDictionary dictionaryWithObjectsAndKeys: primaryColor, NSForegroundColorAttributeName,  
  11.                                            [NSFont systemFontOfSize:13], NSFontAttributeName, nil nil];  
  12.     NSMutableAttributedString *string = [[[NSMutableAttributedString alloc]initWithString:@"hello world" attributes:primaryTextAttributes]autorelease];  
  13.     [string setAttributes:@{NSForegroundColorAttributeName:[NSColor redColor]} range:NSMakeRange(05)];  
  14.     //[string drawAtPoint:NSMakePoint(cellFrame.origin.x+cellFrame.size.height+10, cellFrame.origin.y+20)];  
  15.     //用下面这个可以使用省略属性  
  16.       
  17.     NSMutableParagraphStyle *ps = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];  
  18.     [ps setLineBreakMode:NSLineBreakByTruncatingTail];  
  19.     NSRange range = NSMakeRange(0, [string length]);  
  20.     [string addAttribute:NSParagraphStyleAttributeName value:ps range:range];  
  21.     [ps release];  
  22.     [string drawInRect:NSMakeRect(cellFrame.origin.x+cellFrame.size.height+15, cellFrame.origin.y+10,40,15)];  
  23.       
  24.     NSImage *icon = [NSImage imageNamed:@"1"];  
  25.       
  26.     //icon = [self roundCorners:icon];圆形  
  27.   
  28.     //这句很重要,如果没有Y轴的移偏,看到的只有第一行有头像  
  29.     float yOffset = cellFrame.origin.y;  
  30.   
  31.     [icon drawInRect:NSMakeRect(cellFrame.origin.x+5,yOffset + 3,cellFrame.size.height-6, cellFrame.size.height-6)  
  32.                     fromRect:NSMakeRect(0,0,[icon size].width, [icon size].height)  
  33.                    operation:NSCompositeSourceOver  
  34.             fraction:1.0 respectFlipped:YES hints:nil];  
  35. }  

问题二:有时候在工作中,我们对满足某一条件的行或列进行锁定,不让用户进行编辑或随意拖动。

这个稍有点简单,主要是利用下面的代理来完成之。

[objc] view plaincopy在CODE上查看代码片派生到我的代码片
  1. /*========================================================================================== 
  2. *    设置某行是否可以被选中,返回YES,则可以选中,返回NO 则不可选中,即没有高亮选中 
  3. *    用于控制某一行是否可以被选中,前提是selectionShouldChangeInTableView:必须返回YES 
  4. *===========================================================================================*/  
  5. - (BOOL)tableView:(NSTableView *)tableView shouldSelectRow:(NSInteger)row  
  6. {  
  7.     if (row == 2)  
  8.     {  
  9.         return NO;  
  10.     }  
  11.           
  12.     return YES;  
  13. }  
  14.   
  15. - (NSIndexSet *)tableView:(NSTableView *)tableView selectionIndexesForProposedSelection:(NSIndexSet *)proposedSelectionIndexes  
  16. {  
  17.     return proposedSelectionIndexes;  
  18. }  
  19.   
  20. - (BOOL)tableView:(NSTableView *)tableView shouldSelectTableColumn:(NSTableColumn *)tableColumn  
  21. {  
  22.     if ([tableColumn.identifier isEqualToString:kMCButtontColumnID]) {  
  23.         return YES;  
  24.     }  
  25.     return NO;  
  26. }  

问题三:这个问题上需要费点劲,为什么呢,如果做 MAC 的话你会发现,NSView是不会自动响应MouseMove事件的,同时NSTableView也不会自动响应MouseMove事件的。况且现在是Cell-base没有View.本想利用NSView上的鼠标事件来实现移出移入单元格的思路也被卡掉了。哪么就没有办法了吗?办法总是有的,只是好用不好用,易用不易用罢了,下面我说下我的实现思路,如果有MAC高手发现不对就指教了。

1。让tableView支持mouseMove事件。

2。想办法把mouseMove事件中的鼠标坐标点转换为tableView对应的行和列。

先解决第一点,要想有mouseMove事件,先得让tableView有焦点。有时候自己手工创建的tableView 由于窗口上有好多View而使得tableView当前不在焦点上,因此可以借住第一响就这个方式来使之成为第一响应。

[objc] view plaincopy在CODE上查看代码片派生到我的代码片
  1. - (void)focus:(NSWindow *) owner  
  2. {  
  3.     [owner makeFirstResponder:m_tableView];  
  4. }  
其次还必须把NSTableView 的接受鼠标事件开启:

[objc] view plaincopy在CODE上查看代码片派生到我的代码片
  1. [m_tableView.window setAcceptsMouseMovedEvents:YES];  
好,现在NSTableView有鼠标移动事件了,现在关键是确定鼠标移动点是在哪一行和列上,细看NSTableView的接口你会发现有这样两个方法:

[objc] view plaincopy在CODE上查看代码片派生到我的代码片
  1. /* Returns the column index at 'point', or -1 if 'point' is outside of all table columns. 
  2.  */  
  3. - (NSInteger)columnAtPoint:(NSPoint)point;  
  4.   
  5. - (NSInteger)rowAtPoint:(NSPoint)point;  
但注意这里的point,与鼠标的坐标不同,鼠标是相对于screen的,需要转换到app上来,怎么转?
[objc] view plaincopy在CODE上查看代码片派生到我的代码片
  1. NSPoint p = [self convertPoint:[theEvent locationInWindow] fromView:nil];  
这样一句就可以转过来了。

好吧,有了这些信息哪么就好办了,现在还有一个关键点。就是这个行与行,列与列之间的事件触发。因此必须很精确的判断出来。具体看码吧。

[objc] view plaincopy在CODE上查看代码片派生到我的代码片
  1. - (BOOL)RTMouseInRect:(NSRect) rect withPoint:(NSPoint)pt  
  2. {  
  3.     // +2是因为有一个边框的大小为1  
  4.     float xpos = ceilf(pt.x); //向上取整  
  5.     float ypos = ceilf(pt.y);  
  6.     if ((xpos >= rect.origin.x) && ( xpos <= rect.origin.x + rect.size.width +2)  
  7.         && (ypos >= rect.origin.y) && ypos <= rect.origin.y + rect.size.height+2)  
  8.     {  
  9.         return YES;  
  10.     }  
  11.     return NO;  
  12. }  
  13.   
  14. static NSRect prevRect;  
  15. - (void)mouseMoved:(NSEvent *)theEvent  
  16. {  
  17.     //NSLog(@"mouseMoved theEvent = %@",theEvent);  
  18.     NSPoint p = [self convertPoint:[theEvent locationInWindow] fromView:nil];  
  19.   
  20.     long column = [self columnAtPoint:p];  
  21.   
  22.     long row = [self rowAtPoint:p];  
  23.   
  24.     if(column != -1 && row != -1)  
  25.     {  
  26.         //NSLog(@"col = %ld",column);  
  27.         // NSLog(@"row = %ld",row);  
  28.           
  29.        // NSLog(@"pppppp = %@",NSStringFromPoint(p));  
  30.           
  31.         //NSLog(@"self.rowHeight = %f",self.rowHeight);  
  32.           
  33.         NSTableColumn* theColumn = [[self tableColumns] objectAtIndex:column];  
  34.   
  35.         //NSLog(@"theColumn = %@",theColumn);  
  36.         //NSLog(@"theColumn.dataCell = %@",theColumn.dataCell);  
  37.         //NSCell *dataCell = [theColumn dataCellForRow:row];//取到的类型不对,一直是NSTextFieldCell的,不是自己定义的  
  38.         //NSLog(@"dataCell = %@",dataCell);  
  39.           
  40.         //只有用这种方法才可以取到正确的自定义cell  
  41.         NSCell *customcell = [self preparedCellAtColumn:column row:row];  
  42.         //NSLog(@"customcell = %@",customcell);  
  43.           
  44.         NSRect rect = [self frameOfCellAtColumn:column row:row];  
  45.           
  46.         //前后发生变化时  
  47.         if (![NSStringFromRect(prevRect) isEqualToString:NSStringFromRect(rect)])  
  48.         {  
  49.             BOOL enter = [self RTMouseInRect:prevRect withPoint:p];  
  50.             if (!enter && ![NSStringFromRect(prevRect) isEqualToString:NSStringFromRect(NSZeroRect)])  
  51.             {  
  52.                  //NSLog(@"outter");  
  53.                 NSIndexSet *idxset = [self columnIndexesInRect:prevRect];  
  54.                 NSUInteger col = [idxset lastIndex];  
  55.                 //NSArray * cols =[[self tableColumns]objectsAtIndexes:idxset]; //也可以取到  
  56.                 NSTableColumn* colobj = [[self tableColumns] objectAtIndex:col];  
  57.                 NSRange rg = [self rowsInRect:prevRect];  
  58.                 NSUInteger preRow = rg.location;  
  59.                 id cell = [self preparedCellAtColumn:col row:preRow];  
  60.                   
  61.                 if ([delegate respondsToSelector:@selector(mouseExitTableViewCell:cell:column:row:)]) {  
  62.                     [delegate mouseExitTableViewCell:self cell:cell column:colobj row:preRow];  
  63.                 }  
  64.             }  
  65.               
  66.             enter = [self RTMouseInRect:rect withPoint:p];  
  67.             if (enter)  
  68.             {  
  69.                 //NSLog(@"enter ");  
  70.                 if ([delegate respondsToSelector:@selector(mouseEnterTableViewCell:cell:column:row:)]) {  
  71.                     [delegate mouseEnterTableViewCell:self cell:customcell column:theColumn row:row];  
  72.                 }  
  73.             }  
  74.         }  
  75.           
  76.         prevRect = rect;  
  77.           
  78.     }  
  79.     else  
  80.     {  
  81.         if (![NSStringFromRect(prevRect) isEqualToString:NSStringFromRect(NSZeroRect)])  
  82.         {  
  83.             //NSLog(@"outter");  
  84.             NSIndexSet *idxset = [self columnIndexesInRect:prevRect];  
  85.             NSUInteger col = [idxset lastIndex];  
  86.             //NSArray * cols =[[self tableColumns]objectsAtIndexes:idxset]; //也可以取到  
  87.             NSTableColumn* colobj = [[self tableColumns] objectAtIndex:col];  
  88.             NSRange rg = [self rowsInRect:prevRect];  
  89.             NSUInteger preRow = rg.location;  
  90.             id cell = [self preparedCellAtColumn:col row:preRow];  
  91.              
  92.             if ([delegate respondsToSelector:@selector(mouseExitTableViewCell:cell:column:row:)]) {  
  93.                 [delegate mouseExitTableViewCell:self cell:cell column:colobj row:preRow];  
  94.             }  
  95.         }  
  96.         prevRect = NSZeroRect;  
  97.     }  
  98.     [super mouseMoved:theEvent];  
  99. }  
  100.   
  101. - (void)scrollWheel:(NSEvent *)theEvent  
  102. {  
  103.     NSLog(@"wheel theEvent = %@",theEvent);  
  104.       
  105.     [super scrollWheel:theEvent];  
  106.     //滚动时触发一下鼠标移动事件  
  107.     [self mouseMoved:theEvent];  
  108. }  
下面是通过代理打印出来的信息:


问题四:一般情况下,对于每行高度是固定的,哪就没有什么好说的了,实现

[objc] view plaincopy在CODE上查看代码片派生到我的代码片
  1. - (CGFloat)tableView:(NSTableView *)tableView heightOfRow:(NSInteger)row  

就可以了,但如果是某行的高度是动态的,哪对于cell-base还真有点麻烦。为什么,因为cell只有在绘制出来的时候都好确定cell的大小,不像View,可以直接用frame就可以确定。cell不一样,cell初始代的时候是是(40000,40000)宽高。你总不能把这个当作动态高度吧。因此在Cell中必须使用cellSize或cellSizeForBounds 来确定高度。

看下效果:



具体的算法:

[objc] view plaincopy在CODE上查看代码片派生到我的代码片
  1. -(NSSize)cellSizeForBounds:(NSRect)aRect  
  2. {  
  3.   
  4.     NSSize tmp = NSMakeSize(aRect.size.width, aRect.size.height);  
  5.     if (display) {  
  6.         //tmp.height = [self heightForStringDrawing:display andFont:[NSFont fontWithName:@"Helvetica" size:13] withWidth:tmp.width -20]+20;  
  7.           
  8.         NSRect rect = [self getstringHeighInWith:tmp.width -20 byString:display];  
  9.         tmp.height = CGRectGetHeight(rect)+20;  
  10.     }  
  11.     else  
  12.     {  
  13.         tmp.height = 0;  
  14.     }  
  15.     return tmp;  
  16. }  
  17.   
  18. -(NSSize)cellSize  
  19. {  
  20.     NSSize tmp = [super cellSize];  
  21.     if (display) {  
  22.         //tmp.height = [self heightForStringDrawing:display andFont:[NSFont systemFontOfSize:13] withWidth:230]+20;  
[objc] view plaincopy在CODE上查看代码片派生到我的代码片
  1. <pre code_snippet_id="172750" snippet_file_name="blog_20140127_12_624697" name="code" class="objc">        NSRect rect = [self getstringHeighInWith:tmp.width -20 byString:display];  
  2.         tmp.height = CGRectGetHeight(rect)+20;</pre> } else { tmp.height = 0; } return tmp;}- (NSRect)getstringHeighInWith:(float)width byString:(NSString *)string{ NSMutableParagraphStyle *ps = [[NSParagraphStyle defaultParagraphStyle] mutableCopy]; [ps setLineBreakMode:NSLineBreakByCharWrapping];  
  3.  ps.alignment = NSJustifiedTextAlignment; NSDictionary* primaryTextAttributes = [NSDictionary dictionaryWithObjectsAndKeys: [NSColor blackColor], NSForegroundColorAttributeName, [NSFont fontWithName:@"Helvetica" size:13], NSFontAttributeName, NSParagraphStyleAttributeName,ps,nil];  
  4.  NSRect rect = [string boundingRectWithSize:NSMakeSize(width, 4000) options:NSStringDrawingUsesLineFragmentOrigin attributes:primaryTextAttributes]; return rect;}<p></p>  
  5. <pre></pre>  
  6. <br>  
  7. 其次是在高度返回值中处理:  
  8. <p></p>  
  9. <p></p><pre code_snippet_id="172750" snippet_file_name="blog_20140127_13_7800014" name="code" class="objc">- (CGFloat)tableView:(NSTableView *)tableView heightOfRow:(NSInteger)row  
  10. {  
  11.   
  12.     NSTableColumn *column = [[tableView tableColumns] objectAtIndex:0];  
  13.     NSCell *dycell = [tableView preparedCellAtColumn:0 row:row];  
  14.     NSRect cellBounds = NSZeroRect;  
  15.     cellBounds.size.width = [column width]; cellBounds.size.height = FLT_MAX;  
  16.     NSSize cellSize = [dycell cellSizeForBounds:cellBounds];  
  17.     return cellSize.height;  
  18. }</pre><br>  
  19. 以上可以实现动态高度了,但还有一点,就是列拖动大小的时候,行的高度不变,哪怎么处理呢?幸好,tableView已为我们提供了便捷的刷新方法:<p></p>  
  20. <p></p><pre code_snippet_id="172750" snippet_file_name="blog_20140127_14_4418924" name="code" class="objc">- (void)tableViewColumnDidResize:(NSNotification *)aNotification  
  21. {  
  22.     NSTableView* aTableView = aNotification.object;  
  23.     NSIndexSet *indexes = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0,aTableView.numberOfRows)];  
  24.     [aTableView noteHeightOfRowsWithIndexesChanged:indexes];  
  25. }</pre>即<pre code_snippet_id="172750" snippet_file_name="blog_20140127_15_9642394" name="code" class="objc">[aTableView noteHeightOfRowsWithIndexesChanged:indexes];</pre>和<br>  
  26. <pre code_snippet_id="172750" snippet_file_name="blog_20140127_16_2357610" name="code" class="objc">- (void)noteNumberOfRowsChanged;</pre>我们只需要在列大小改变的时候调用就OK了,我的代码里是用窗口大小变化来触发的。具体以实际情况而定了。<br>  
  27. <br>  
  28. 问题五:<p></p>  
  29. <p>tableView自身的选中色为蓝色的。要想改变,有两种变通的方法。</p>  
  30. <p>1.利用NSCell进行设置,注意这种处理方法,是针对每个格子的进行设置,比如有1234列,如果每例的Cell设置得不同的时候,你会发现当选中一行时,显示为不同的选中色了。样例代码。这个用法,需要注意有表格线和没有表格线时的表示,否则你会看到蓝色线条。</p>  
  31. <p></p><pre code_snippet_id="172750" snippet_file_name="blog_20140127_17_9740670" name="code" class="objc">//自个画,,,,,  
  32. - (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView  
  33. {  
  34.     BOOL elementDisabled = NO;  
  35.     NSColor* primaryColor   = [self isHighlighted] ? [NSColor alternateSelectedControlTextColor] : (elementDisabled? [NSColor disabledControlTextColor] : [NSColor textColor]);  
  36.       
  37.     NSDictionary* primaryTextAttributes = [NSDictionary dictionaryWithObjectsAndKeys: primaryColor, NSForegroundColorAttributeName,  
  38.                                            [NSFont systemFontOfSize:13], NSFontAttributeName, nil nil];  
  39.     [self.displayName.stringValue drawAtPoint:NSMakePoint(cellFrame.origin.x+cellFrame.size.height+10, cellFrame.origin.y) withAttributes:primaryTextAttributes];  
  40.     //画图  
  41.     [[NSGraphicsContext currentContext] saveGraphicsState];  
  42.     float yOffset = cellFrame.origin.y;  
  43.     if ([controlView isFlipped]) {  
  44.         NSAffineTransform* xform = [NSAffineTransform transform];  
  45.         [xform translateXBy:0.0 yBy: cellFrame.size.height];  
  46.         [xform scaleXBy:1.0 yBy:-1.0];  
  47.         [xform concat];  
  48.         yOffset = 0-cellFrame.origin.y;  
  49.     }  
  50.       
  51.     NSImageInterpolation interpolation = [[NSGraphicsContext currentContext] imageInterpolation];  
  52.     [[NSGraphicsContext currentContext] setImageInterpolation: NSImageInterpolationHigh];  
  53.       
  54.     [avatar.image drawInRect:NSMakeRect(cellFrame.origin.x+5,yOffset+3,cellFrame.size.height-6, cellFrame.size.height-6)  
  55.             fromRect:NSMakeRect(0,0,[avatar.image size].width, [avatar.image size].height)  
  56.            operation:NSCompositeSourceOver  
  57.             fraction:1.0];  
  58.       
  59.     [[NSGraphicsContext currentContext] setImageInterpolation: interpolation];  
  60.       
  61.     [[NSGraphicsContext currentContext] restoreGraphicsState];  
  62. }  
  63.   
  64. - (NSAttributedString*)getCellAttributes  
  65. {  
  66.     NSDictionary*  _attributes = [NSDictionary dictionaryWithObjectsAndKeys:_cellFontColor,NSForegroundColorAttributeName,nil];  
  67.     NSString* _cellString = [self stringValue];  
  68.       
  69.     _cellAttributedString = [[[NSAttributedString alloc]  
  70.                               initWithString:_cellString attributes:_attributes] autorelease];  
  71.       
  72.     return _cellAttributedString;  
  73. }  
  74.   
  75. - (NSColor*)highlightColorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView  
  76. {  
  77.     NSRect newRect = NSMakeRect(cellFrame.origin.x - 1, cellFrame.origin.y, cellFrame.size.width + 5, cellFrame.size.height);  
  78.     if (_cellBKColor)  
  79.     {  
  80.         [_cellBKColor set];  
  81.         NSRectFill(newRect);  
  82.     }  
  83.       
  84.     [self setAttributedStringValue:[self getCellAttributes]];  
  85.       
  86.     return nil;  
  87. }</pre><p></p>  
  88. <p>第2种,也是我比较喜欢的吧,不过需要继承NSTableView来实现。</p>  
  89. <p class="p1">- (<span class="s1">id</span>)_highlightColorForCell:(<span class="s1">id</span>)cell;进行重写。</p>  
  90. <p class="p1"></p><pre code_snippet_id="172750" snippet_file_name="blog_20140127_18_4407734" name="code" class="objc">//重写  
  91. - (id)_highlightColorForCell:(id)cell  
  92. {  
  93.       
  94.     if([self selectionHighlightStyle] == 1)  
  95.     {  
  96.         return nil;  
  97.     }  
  98.     else  
  99.     {  
  100.         return [NSColor redColor];//_highlightBKColor;  
  101.     }  
  102. }</pre><br>  
  103. 问题六:<p></p>  
  104. <p class="p1">这个问题是当你绘制出来的字体,不支持鼠标选中操作。</p>  
  105. <p class="p1">这个问题,还没有解决,初步确认是用这四个方法进行实现,但我还没有研究透。还在找资料。(也请高手指点)</p>  
  106. <p class="p1"></p><pre code_snippet_id="172750" snippet_file_name="blog_20140127_19_6043153" name="code" class="objc">- (BOOL)trackMouse:(NSEvent *)theEvent inRect:(NSRect)cellFrame ofView:(NSView *)controlView untilMouseUp:(BOOL)flag;  
  107. - (void)editWithFrame:(NSRect)aRect inView:(NSView *)controlView editor:(NSText *)textObj delegate:(id)anObject event:(NSEvent *)theEvent;  
  108. - (void)selectWithFrame:(NSRect)aRect inView:(NSView *)controlView editor:(NSText *)textObj delegate:(id)anObject start:(NSInteger)selStart length:(NSInteger)selLength;  
  109. - (void)endEditing:(NSText *)textObj;</pre><br>  
  110. 问题七:<p></p>  
  111. <p class="p1">对于部分字体的高亮,通常会出现在搜索时的显示结果上。哪这又是怎么处理的呢?其它也是通过属性字段进行设置不同的字体色进行Draw上来的。</p>  
  112. <p></p><pre code_snippet_id="172750" snippet_file_name="blog_20140127_20_3774879" name="code" class="objc">- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView  
  113. {  
  114.     NSColor* primaryColor   = [self isHighlighted] ? [NSColor alternateSelectedControlTextColor] : [NSColor textColor];  
  115.       
  116.     if (name && phone && highlightkey)  
  117.     {  
  118.         NSDictionary* primaryTextAttributes = [NSDictionary dictionaryWithObjectsAndKeys: primaryColor, NSForegroundColorAttributeName,  
  119.                                                [NSFont systemFontOfSize:12], NSFontAttributeName, nil nil];  
  120.         NSMutableAttributedString *namestring = [[NSMutableAttributedString alloc]initWithString:name attributes:primaryTextAttributes];  
  121.           
  122.         [namestring beginEditing];  
  123.           
  124.         NSRange namerg = [name rangeOfString:highlightkey];  
  125.         [namestring setAttributes:@{NSForegroundColorAttributeName:[NSColor redColor]} range:namerg];  
  126.           
  127.         NSMutableAttributedString *phonestring = [[NSMutableAttributedString alloc]initWithString:phone attributes:primaryTextAttributes];  
  128.         NSRange phonerg = [phone rangeOfString:highlightkey];  
  129.         [phonestring setAttributes:@{NSForegroundColorAttributeName:[NSColor redColor]} range:phonerg];  
  130.         NSMutableAttributedString *left = [[NSMutableAttributedString alloc]initWithString:@"(" attributes:primaryTextAttributes];  
  131.         NSMutableAttributedString *right = [[NSMutableAttributedString alloc]initWithString:@")" attributes:primaryTextAttributes];  
  132.         [namestring appendAttributedString:left];  
  133.         [namestring appendAttributedString:phonestring];  
  134.         [namestring appendAttributedString:right];  
  135.           
  136.         NSMutableParagraphStyle *ps = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];  
  137.         [ps setLineBreakMode:NSLineBreakByTruncatingTail];  
  138.         NSRange range = NSMakeRange(0, [namestring length]);  
  139.         [namestring addAttribute:NSParagraphStyleAttributeName value:ps range:range];  
  140.         [ps release];  
  141.   
  142.         [namestring endEditing];  
  143.           
  144.         CGFloat xpos = cellFrame.origin.x+cellFrame.size.height+15;  
  145.         CGFloat w = cellFrame.size.width - xpos - 30;  
  146.         [namestring drawInRect:NSMakeRect(xpos, cellFrame.origin.y+10,w,15)];  
  147.           
  148.         [right release];  
  149.         [left release];  
  150.         [namestring release];  
  151.         [phonestring release];  
  152.     }  
  153.       
  154.     if (ringUser)  
  155.     {  
  156.         [ringImg drawInRect:NSMakeRect(cellFrame.origin.x+9.5,cellFrame.origin.y + 1,3636)  
  157.                    fromRect:NSMakeRect(0,0,ringImg.size.width, ringImg.size.height)  
  158.                   operation:NSCompositeSourceOver  
  159.                    fraction:1.0 respectFlipped:YES hints:nil];  
  160.     }  
  161.       
  162.     if (avatar)  
  163.     {  
  164.         [[NSGraphicsContext currentContext] saveGraphicsState];  
  165.         NSRect rt = NSMakeRect(cellFrame.origin.x+12.5,cellFrame.origin.y + 4,3030);  
  166.         CGFloat radius = 15;  
  167.         NSBezierPath *clipPath = [NSBezierPath bezierPathWithRoundedRect:rt xRadius:radius yRadius:radius];  
  168.         [clipPath setWindingRule:NSEvenOddWindingRule];  
  169.         [clipPath addClip];  
  170.           
  171.         [avatar drawInRect: rt  
  172.                 fromRect:NSMakeRect(0,0,avatar.size.width, avatar.size.height)  
  173.                operation:NSCompositeSourceOver  
  174.                 fraction:1.0 respectFlipped:YES hints:nil];  
  175.           
  176.         [[NSGraphicsContext currentContext] restoreGraphicsState];  
  177.     }  
  178. }  
  179. </pre><br>  
  180. 其中<pre code_snippet_id="172750" snippet_file_name="blog_20140127_21_5933687" name="code" class="objc">highlightkey就是需要设置为高亮的部分。</pre><p></p>  
  181. <p>欢迎路过大侠多多指教。</p>  
  182. <p><br>  
  183. </p>  
  184. <p>好了,有点多,也有点杂。大家需要慢慢体会。源码我都放在:http://download.csdn.net/detail/fengsh998/6887159</p>  
  185. <p><br>  
  186. </p>  
  187. <p>马上回家过年,这是2013贺岁篇,也正好是在csdn发表文章的第100篇。记念一下。</p>  
  188. <p>同时也祝自己马年,天马流星,神马飞扬,马到功成,马上有想法,马上有伯乐,马上当BOSS,马上开挂,最后辛苦的一年即将过去,来年心想事成,万事如意。</p>  
  189. <p>好,收拾 东东,马上回家。。。。。。</p>  
  190. <br>  
  191. <br>  
  192. <br>  
  193. <br>  
  194. <br>  
  195. <p><br>  
  196. </p>  
  197. <p><br>  
  198. </p>  
0 0
原创粉丝点击