要想给tableview添加复选框就要重定义那一列的cell,通过重写绘图事件和点击事件来实现。
1.重定义cell
YepCheckImageCell.h
#import <Cocoa/Cocoa.h> @interface YepCheckImageCell : NSButtonCell { BOOL isChecked; NSImage* checkImage[2]; NSUInteger imageOffset; } @property (readwrite,assign) BOOL isChecked; @end
YepCheckImageCell.m
#import "YepCheckImageCell.h" @implementation YepCheckImageCell @synthesize isChecked; -(void)awakeFromNib { //初始化复选框图片 NSString *checkPath = [[NSBundle mainBundle] pathForResource:@"check-yes" ofType:@"png"]; checkImage[1] = [[NSImage alloc] initByReferencingFile:checkPath]; NSString *uncheckPath = [[NSBundle mainBundle] pathForResource:@"check-no" ofType:@"png"]; checkImage[0] = [[NSImage alloc] initByReferencingFile:uncheckPath]; //设置偏移量 imageOffset = 6; } -(NSRect)drawTitle:(NSAttributedString *)title withFrame:(NSRect)frame inView:(NSView *)controlView { NSRect imageRect = frame; NSImage *image = checkImage[isChecked]; imageRect.origin.x += imageOffset; imageRect.origin.y += (imageRect.size.height - image.size.height)/2; imageRect.size = image.size; [image drawInRect:imageRect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1 respectFlipped:YES hints:nil]; frame.origin.x += image.size.width + imageOffset * 2; return [super drawTitle:title withFrame:frame inView:controlView]; } -(BOOL)trackMouse:(NSEvent *)theEvent inRect:(NSRect)cellFrame ofView:(NSView *)controlView untilMouseUp:(BOOL)flag { //如果不是点击事件直接返回 if([theEvent type]!= NSLeftMouseDown) { return NSCellHitContentArea; } //获取点击坐标在表格的行数 NSTableView *myView = (NSTableView *)controlView; NSPoint p = [theEvent locationInWindow]; NSPoint local_point = [myView convertPoint:p fromView:nil]; NSUInteger row = [myView rowAtPoint:local_point]; NSImage *image = checkImage[isChecked]; //判断点击的位置是在复选框内 if (local_point.x >= imageOffset && local_point.x <= (image.size.width + imageOffset)) { [[myView delegate] performSelector:@selector(setCheckItem:) withObject:[NSNumber numberWithInteger:row]]; return NSCellHitContentArea; } return NSNullCellType; } @end
2.自定义表头添加一键全选功能
YepTableHeaderView.h
#import <Cocoa/Cocoa.h> @interface YepTableHeaderView : NSTableHeaderView { NSImage* checkImage[2]; BOOL isChecked; int imageOffset; } @end
#import "YepTableHeaderView.h" @implementation YepTableHeaderView - (id)initWithFrame:(NSRect)frame { self = [super initWithFrame:frame]; if (self) { // Initialization code here. } return self; } -(void)awakeFromNib { NSString* checkPath = [[NSBundle mainBundle] pathForResource:@"check-yes" ofType:@"png"]; checkImage[1] = [[NSImage alloc] initByReferencingFile:checkPath]; NSString* uncheckPath = [[NSBundle mainBundle] pathForResource:@"check-no" ofType:@"png"]; checkImage[0] = [[NSImage alloc] initByReferencingFile:uncheckPath]; isChecked = 0; imageOffset = 9; } - (void)drawRect:(NSRect)dirtyRect { // Drawing code here. NSArray* tableColumn = [[self tableView ]tableColumns]; //画背景 [[NSColor lightGrayColor] set]; NSRectFill(dirtyRect); //画复选框 NSImage* image = checkImage[isChecked]; NSRect imageRect = dirtyRect; imageRect.origin.x = imageOffset; imageRect.origin.y = imageRect.origin.y+(imageRect.size.height - image.size.height)/2; imageRect.size = image.size; [image drawInRect:imageRect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1 respectFlipped:YES hints:nil]; //画表头标题 for (int i = 0; i < tableColumn.count ; ++i) { [[NSColor colorWithCalibratedRed: 38/255.0 green:38/255.0 blue:38/255.0 alpha:1] setStroke]; NSTableColumn* column = [tableColumn objectAtIndex:i]; NSRect rect = [self headerRectOfColumn:i]; NSPoint buttomBegin = rect.origin; NSPoint buttomEnd = buttomBegin; buttomEnd.y += rect.size.height; NSString* headerStr = [[column headerCell] stringValue]; NSColor *txtColor = [NSColor colorWithCalibratedRed: 120/255.0 green:127/255.0 blue:133/255.0 alpha:1]; NSFont *txtFont = [NSFont systemFontOfSize:14]; NSSize size = [headerStr sizeWithAttributes:nil]; NSPoint pb = rect.origin; pb.x += 4; if (i==0) { pb.x += checkImage[0].size.width + 10; txtColor = [NSColor colorWithCalibratedRed: 0.0 green:0.0 blue:0.0 alpha:1]; txtFont =[NSFont fontWithName:@"Arial" size:12]; } if (i>=1) { //pb.x +=5; txtColor = [NSColor colorWithCalibratedRed: 99/255.0 green: 99/255.0 blue: 99/255.0 alpha:1]; txtFont =[NSFont fontWithName:@"Arial" size:12]; } NSDictionary *txtDict = [NSDictionary dictionaryWithObjectsAndKeys: txtFont, NSFontAttributeName, txtColor, NSForegroundColorAttributeName, nil]; NSAttributedString *attrStr = [[NSAttributedString alloc] initWithString:headerStr attributes:txtDict]; pb.y = rect.origin.y+(rect.size.height - size.height)/2; [attrStr drawAtPoint:pb]; } [[NSColor colorWithCalibratedRed: 0/255.0 green:0/255.0 blue:0/255.0 alpha:0.5] setStroke]; } - (void)mouseDown:(NSEvent *)theEvent { isChecked = !isChecked; NSSize size = [checkImage[isChecked] size]; NSPoint p = [theEvent locationInWindow]; NSPoint local_point = [self convertPoint:p fromView:nil]; NSRect imageRect = self.frame; local_point.y = imageRect.origin.y; CGFloat xr = imageOffset+size.width+20; imageRect.origin.x = xr; imageRect.size.width = size.width; imageRect.size.height = size.height; if (local_point.x<xr && local_point.x > imageOffset) { NSTableView *myView = [self tableView]; [myView.delegate performSelector:@selector(setHeaderCheckItem:) withObject:[NSNumber numberWithInteger:isChecked]]; [self setNeedsDisplay:YES]; } //1.如果调用父的mouseDown,MouseUp就不会调用. [super mouseDown:theEvent]; } @end
3.在表格代理类种定义函数来改变表格数据,这里用的是setCheckItem,根据行号来动态修改复选框的状态
-(void) setCheckItem:(id) data { NSNumber *row = data; SimpleData *item = [array objectAtIndex:row.integerValue]; [item setIsChecked:!item.isChecked]; NSIndexSet *rowSet = [NSIndexSet indexSetWithIndex:[row integerValue]]; NSIndexSet *columnSet = [NSIndexSet indexSetWithIndex:0]; [tableView reloadDataForRowIndexes:rowSet columnIndexes:columnSet]; }
4.在表格代理类中定义函数来全选
-(void) setHeaderCheckItem:(id) data { NSNumber *value = data; for (SimpleData *data in array) { [data setIsChecked:[value boolValue]]; } [tableView reloadData]; }
表头最右边是需要重绘的,这里自定义一个view:
YepTableCornerView.h
#import <Cocoa/Cocoa.h> @interface YepTableCornerView : NSView @endYepTableCornerView.m
#import "YepTableCornerView.h" @implementation YepTableCornerView - (id)initWithFrame:(NSRect)frame { self = [super initWithFrame:frame]; if (self) { // Initialization code here. } return self; } - (void)drawRect:(NSRect)dirtyRect { // Drawing code here. //填充角view的颜色 [[NSColor colorWithCalibratedRed: 255/255.0 green:255/255.0 blue:255/255.0 alpha:1] setFill]; NSRectFill(dirtyRect); //画角view的边 NSBezierPath *line = [NSBezierPath bezierPath]; [line setLineWidth:1]; [[NSColor colorWithCalibratedRed: 255/255.0 green:255/255.0 blue:255/255.0 alpha:1] setStroke]; NSPoint endPoint = dirtyRect.origin; endPoint.x += dirtyRect.size.width; [line moveToPoint:dirtyRect.origin]; [line lineToPoint:endPoint]; [line stroke]; NSPoint buttomBegin = dirtyRect.origin; buttomBegin.y += dirtyRect.size.height; NSPoint buttomEnd = endPoint; buttomEnd.y += dirtyRect.size.height; [line moveToPoint:buttomBegin]; [line lineToPoint:buttomEnd]; [line stroke]; } @end
表格代理类中要主动调用设置表格角view
YepTableCornerView *coreView = [[YepTableCornerView alloc] init]; [tableView setCornerView:coreView];
5.效果:
项目代码例子下载地址:http://download.csdn.net/detail/yepeng2014/9184111
要是NSTableView不懂的可以参考这篇:http://blog.csdn.net/yepeng2014/article/details/49026773