基于视图的NSTableView选择突出显示

the*_*tic 5 macos objective-c nstableview nstableviewcell

我正在尝试将iOS应用程序移植到Mac上,并且在转换过程中遇到了一些问题.其中之一是定制NSTableView.究竟是什么区别NSCell,NSTableRowView和自定义NSView基于NSTableview?我最初开始时基于视图NSTableView,但我很快注意到我必须自己处理选择.我无法将其拉下来,所以我继续使用NSTableRowView,奇怪的是,它并没有调用我习惯的初始化器NSTableRowView.

我基本上只想要一个具有自定义内容的自定义表格视图单元格,这是可选择的.最好的方法是什么?

在iOS上,我只是子类UITableViewCell并设置其selectedView属性.在Mac上,这似乎比这更复杂.

the*_*tic 18

我实际上刚刚发现(在侧边栏中)这个问题,建议继承NSTableRowView.我之前已经这样做了,但它没有用.我再试过一次,很奇怪它现在有效......

在基于NSTableView的视图中处理自定义选择样式

但是,这个答案并不是很有用,所以我将尝试介绍我为完成这项工作所做的工作.

首先,我实现了以下NSTableView委托方法并返回nil!:

- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row{

    return nil;

}
Run Code Online (Sandbox Code Playgroud)

为了使用基于视图(我猜NSTableViewRow被视为基于视图的表...)表,您必须实现此方法.我不太确定我可能做错了什么,但如果没有这种方法,我的细胞就不会显示!

确保不要让NSTableView通过设置此属性来处理任何选择:

yourNSTableView.selectionHighlightStyle = NSTableViewSelectionHighlightStyleNone;
Run Code Online (Sandbox Code Playgroud)

好的,现在我们要使用以下委托方法设置我们的单元格:

-(NSTableRowView *)tableView:(NSTableView *)tableView rowViewForRow:(NSInteger)row{

    static NSString *cellID = @"cell_identifier";

    //use this if you want to reuse the cells
    CustomTableRowView *result = [tableView makeViewWithIdentifier:cellID owner:self];

    if (result == nil) {

        result = [[CustomTableRowView alloc] initWithFrame:NSMakeRect(0, 0, self.frame.size.width, 80)];
        result.identifier = cellID;

    }

    result.data = [tableData objectAtIndex:row];

    // Return the result
    return result;

}
Run Code Online (Sandbox Code Playgroud)

好的,现在将子类化NSTableRowView并实现/覆盖以下两种方法:

首先,我们必须覆盖setSelected:,以便在选择单元格时重绘其背景.所以这里是:

-(void)setSelected:(BOOL)selected{

    [super setSelected:selected];
    [self setNeedsDisplay:YES];

}
Run Code Online (Sandbox Code Playgroud)

如前所述,我们调用setNeedsDisplay:以便单元格重绘其背景.

最后,绘图代码.drawBackgroundInRect:像这样重写方法:

-(void)drawBackgroundInRect:(NSRect)dirtyRect{
    if (!self.selected) {
        [[NSColor clearColor] set];
    } else {
        [someColor set];
    }
    NSRectFill(dirtyRect);
}
Run Code Online (Sandbox Code Playgroud)