要想给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
YepTableHeaderView.m
#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
@end
YepTableCornerView.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