基于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;
}


 
 




版权声明:本文为博主原创文章,未经博主允许不得转载。

转载于:https://www.cnblogs.com/RoysPhoneBlog/p/4617244.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值