NSTableView中具有悬停效果的可单击文本

Har*_*Ali 1 cocoa objective-c hover textfield nstableview

我试图创建可点击的URL型一列文本(而不是URL像这样,但本质上与悬停效果的跟踪区域无国界,标题按钮或文本字段细胞)内NSTableView.

1.)当用户将鼠标悬停在特定单元格上时,该单元格中的文本应在文本下方绘制下划线(悬停/可跟踪区域效果).

2.)当用户点击文本时,它应该执行一个动作.

我子类NSCell,并NSTableView与定制的tableview内增加了一个跟踪区域,试图跟踪表的单个电池的鼠标位置通知小区时重绘自身.我可以获取鼠标位置的当前行和列,但似乎无法在我的自定义tableview的mouseMoved:方法中获取正确的单元格

-(void)mouseMoved:(NSEvent *)theEvent {
  [super mouseMoved:theEvent];
  NSPoint p = [self convertPoint:[theEvent locationInWindow] fromView:nil];
  long column = [self columnAtPoint:p];
  long row = [self rowAtPoint:p];
  id cell = [[self.tableColumns objectAtIndex:column] dataCellForRow:row];
}
Run Code Online (Sandbox Code Playgroud)

它获取列的单元格,但没有为该特定行获取正确的单元格.也许我还没有完全理解这个dataCellForRow:功能NSTableColumn

我知道你不能完全加入追踪区域的细胞,而是你必须创建鼠标点击点击测试,然后开始追踪一次命中测试成功(指鼠标已经下降),然后使用startTracking:,continueTracking:以及stopTracking:对得到鼠标的位置.但这个想法是它在任何mouseDown:行动之前都有悬停效果.

此外,我不能只使用基于视图的tableview(这将是不可思议的),因为我的应用程序必须兼容10.6.

rde*_*mar 5

我不确定你获得细胞的方法有什么问题,但你真的不需要那样做你想要的.我测试了一种方法,这需要创建一个表视图子类来在鼠标移动方法中进行跟踪.这是该子类的代码:

-(void)awakeFromNib {
    NSTrackingArea *tracker = [[NSTrackingArea alloc] initWithRect:self.bounds options:NSTrackingMouseEnteredAndExited|NSTrackingMouseMoved|NSTrackingActiveInActiveApp owner:self userInfo:nil];
    [self addTrackingArea:tracker];
    self.rowNum = -1;
}

-(void)mouseMoved:(NSEvent *)theEvent {
    NSPoint p = theEvent.locationInWindow;
    NSPoint tablePoint = [self convertPoint:p fromView:nil];
    NSInteger newRowNum = [self rowAtPoint:tablePoint];
    NSInteger newColNum = [self columnAtPoint:tablePoint];
    if (newColNum != self.colNum || newRowNum != self.rowNum) {
    self.rowNum = newRowNum;
    self.colNum = newColNum;
    [self reloadData];
    }
}

-(void)mouseEntered:(NSEvent *)theEvent {
    [self reloadData];
}

-(void)mouseExited:(NSEvent *)theEvent {
    self.rowNum = -1;
    [self reloadData];
}
Run Code Online (Sandbox Code Playgroud)

我把数组和表委托和数据源代码放在app委托中(可能不是最好的地方,但可以测试).

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    self.theData = @[@{@"name":@"Tom",@"age":@"47"},@{@"name":@"Dick",@"age":@"21"},@{@"name":@"Harry",@"age":@"27"}];
    [self.table reloadData];
    self.dict = [NSDictionary dictionaryWithObjectsAndKeys:@2,NSUnderlineStyleAttributeName,[NSColor redColor],NSForegroundColorAttributeName,nil];
}

- (NSInteger)numberOfRowsInTableView:(RDTableView *)aTableView {
    return self.theData.count;
}


- (id)tableView:(RDTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex {
    if (self.table.colNum == 0 && rowIndex == self.table.rowNum && [aTableColumn.identifier isEqualToString:@"Link"]) {
        NSString *theName = [[self.theData objectAtIndex:rowIndex] valueForKey:@"name"];
        return [[NSAttributedString alloc] initWithString:theName attributes:self.dict];
    }else if ([aTableColumn.identifier isEqualToString:@"Link"]){
        return [[self.theData objectAtIndex:rowIndex] valueForKey:@"name"];
    }else{
        return [[self.theData objectAtIndex:rowIndex] valueForKey:@"age"];
    }
}

- (void)tableViewSelectionDidChange:(NSNotification *)aNotification {
    if (self.table.colNum == 0)
        NSLog(@"%ld",[aNotification.object selectedRow]);
}
Run Code Online (Sandbox Code Playgroud)

我使用委托方法tableViewSelectionDidChange:来实现该操作,如果您单击第一列中的单元格(在IB中设置标识符"链接").