基于base - cell的NSTableView,学习苹果的demo AnimateTableView所写
最近需要开发一个OSX与服务器交互的代码,由于网络上确实很少的资料,只能看了苹果的Demo,学到了以下东西,分享一下,方便以后的同志们再搜索百度的时候有个例子
首先,写NSCell的子类,我拿我自己写的UserNameCell.h
#import <Cocoa/Cocoa.h> enum{ ENUserPoupeCellArea=1<<16 }; @interface UserNameCell : NSTextFieldCell{ @private NSImageCell *_imageCell; //也可以添加多个东西,这里我只加了一个图片用于测试 } @property (retain) NSImageCell *imageCell; @end
UserNameCell.m
// // UserNameCell.m // OSX_Coffee // // Created by Roy on 14-6-22. // Copyright (c) 2014年 byids. All rights reserved. // #import "UserNameCell.h" #import "ATUserInfoTableViewController.h" #import "UserInformation.h" @implementation UserNameCell //拷贝构造,一定要有一个,因为Cell是复制到各个上面去的 -(id)copyWithZone:(NSZone *)zone{ UserNameCell *cell = [super copyWithZone:zone]; cell.imageCell = _imageCell; return cell; } -(void)setImageCell:(NSImageCell *)imageCell{ _imageCell = imageCell; } -(NSImageCell *)imageCell{ return _imageCell; } -(id)init{ self =[super init]; if (self) { _imageCell = [[NSImageCell alloc]init]; [_imageCell setImageScaling:NSImageScaleAxesIndependently]; //图片的拉伸方式 [self setUsesSingleLineMode:NO]; //设置是否单线显示 [self setLineBreakMode:NSLineBreakByTruncatingTail]; //设置文字显示不出来时的显示方式 NSFont *font = [NSFont fontWithName:@"Times" size:17.0]; [self setFont:font]; } return self; } /** *计算按钮的大小 **/ -(NSRect)_imageFrameInteriorFrame:(NSRect)frame{ NSRect result = frame; result.origin.x = NSMaxX(frame)-45; result.origin.y = NSMaxY(frame)-45; result.size = NSMakeSize(30.0, 30.0); return result; } //将文字放在cell的中间 -(NSRect)_titleFrameInterriorFrame:(NSRect)frame{ NSRect result = frame; result.origin.x = NSMinX(frame) +5.0; // Center in the height // Move the title above the Y centerline of the image. NSSize naturalSize = [super cellSize]; result.origin.y = floor(NSMidY(frame) - naturalSize.height / 2.0); result.size.height = naturalSize.height; // Go as wide as we can result.size.width = naturalSize.width; return result; }
//这个函数是重点,当tableview调用 tableview datacolumunfortablecoulum函数的时候会调用 -(void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView{ if (_imageCell) { NSRect infoFrame = [self _imageFrameInteriorFrame:cellFrame]; [_imageCell setImage:[NSImage imageNamed:@"0.png"]]; [_imageCell drawInteriorWithFrame:infoFrame inView:controlView]; } NSRect titleFrame = [self _titleFrameInterriorFrame:cellFrame]; [super drawInteriorWithFrame:titleFrame inView:controlView]; } //鼠标点击测试,返回cell的类型 -(NSUInteger)hitTestForEvent:(NSEvent *)event inRect:(NSRect)cellFrame ofView:(NSView *)controlView{ NSPoint point = [controlView convertPoint:[event locationInWindow] fromView:nil]; NSRect frame = [self _imageFrameInteriorFrame:cellFrame]; if (NSPointInRect(point, frame)) { return NSCellHitTrackableArea|NSCellHitContentArea; }else{ NSUInteger result=[super hitTestForEvent:event inRect:cellFrame ofView:controlView]; return result; } } //追踪鼠标点击消息,只有上面返回了NSCellHitTrackableArea了的区域才会响应这个方法 -(BOOL)trackMouse:(NSEvent *)theEvent inRect:(NSRect)cellFrame ofView:(NSView *)controlView untilMouseUp:(BOOL)flag{ //追踪鼠标点击事件的地方 BOOL result =NO; NSRect frame = [self _imageFrameInteriorFrame:cellFrame]; NSPoint eventPoint = [controlView convertPoint:[theEvent locationInWindow] fromView:nil]; if (NSPointInRect(eventPoint, frame)) { NSRect colorRectFrameInScreenCoordinates = [controlView convertRectToBase:frame]; colorRectFrameInScreenCoordinates.origin = [controlView.window convertBaseToScreen:colorRectFrameInScreenCoordinates.origin]; //todo:在这个地方显示出框框 result = YES; } return result; } @end
以下是NSTableViewDelegate需要实现的函数
-(NSCell *)tableView:(NSTableView *)tableView dataCellForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row{ NSString *strTitle = [tableColumn.headerCell stringValue]; if ([strTitle isEqualToString:@"id"]) { return [tableColumn dataCell]; //需要在xib上添加一个NSCell } else if([strTitle isEqualToString:@"loginName"]){ UserNameCell *cell = [[UserNameCell alloc]init]; return cell; //返回我们自创的cell }else{ return nil; } }
//有了上面的函数,下面的函数才有效 -(void)tableView:(NSTableView *)tableView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row{ NSString *strTitle = [tableColumn.headerCell stringValue]; if ([strTitle isEqualToString:@"id"]) { NSTextFieldCell *idcell = (NSTextFieldCell *)cell; [idcell setTitle:@"1"]; } else if([strTitle isEqualToString:@"loginName"]){ UserNameCell *userCell = (UserNameCell*)cell; [userCell setTitle:[userNameArray objectAtIndex:row]]; } }
<pre name="code" class="objc">-(NSIndexSet *)tableView:(NSTableView *)tableView selectionIndexesForProposedSelection:(NSIndexSet *)proposedSelectionIndexes{ NSInteger row = [tableView clickedRow]; if (row != -1) { UserNameCell *cell = (UserNameCell *)[tableView preparedCellAtColumn:1 row:row]; // Use the hit testing API with our own special marker to find out what we hit //如果我们点中的是那个图片,我们就做事情但是不选中(就是高亮),如果不是就选中 NSUInteger hitTest = [cell hitTestForEvent:[NSApp currentEvent] inRect:[tableView frameOfCellAtColumn:1 row:row] ofView:tableView]; if ((hitTest & NSCellHitContentArea) != 0) { // Don't allow the selection change [cell trackMouse:[NSApp currentEvent] inRect:[tableView frameOfCellAtColumn:1 row:row] ofView:tableView untilMouseUp:NO]; return [tableView selectedRowIndexes]; } self.userLoginName = [cell title]; } else { if (proposedSelectionIndexes.count > 0) { return [tableView selectedRowIndexes]; } } [[NSNotificationCenter defaultCenter]postNotificationName:@"Notification_updateTabView" object:self]; return proposedSelectionIndexes; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
欢迎一起来研究,QQ 253807688