NSTableRowView/NSTableCellView 如何为选定的行设置自定义颜色?

Posted

技术标签:

【中文标题】NSTableRowView/NSTableCellView 如何为选定的行设置自定义颜色?【英文标题】:NSTableRowView/NSTableCellView how to set custom color to selected row? 【发布时间】:2014-10-27 16:43:04 【问题描述】:

我正在尝试在选择表格行时实现自定义行颜色。

-(void)tableViewSelectionDidChange:(NSNotification *)notification


    NSInteger selectedRow = [_mainTable selectedRow];

    NSTableCellView *cell = [_mainTable rowViewAtRow:selectedRow makeIfNecessary:NO];

    cell.layer.backgroundColor = [NSColor redColor].CGColor;

    NSLog(@"selected");

但这不起作用。我发现 Apple 文档非常混乱(也许我错了)。我对 Mac 编程没有经验。

有人可以提出任何解决方案吗?基本上我需要选择颜色是透明的。

【问题讨论】:

@meda 你有什么想法吗? 您的问题已经得到解答。去这里***.com/questions/11920156/… @Rana Tallal 这是 ios 的。 您可以应用与 ios 相同的逻辑。将 selectionstyle 设置为 non,然后在选择时将颜色更改为您想要的颜色。并用动画改回来 @Rana Tallal,是的,我试过了,现在可以了。 【参考方案1】:

解决方案

这应该通过子类化NSTableRowView 然后使用NSTableView 委托方法返回您的子类来完成-(NSTableRowView*)tableView:(NSTableView *)tableView rowViewForRow:(NSInteger)row

子类化NSTableRowView 在修改行视图时提供了更大的灵活性。在上面的 NSTableView 委托方法中返回您的子类 当从一行点击到下一行时,还将自动删除背景选择颜色(这是提供的另一个答案中的一个未解决问题)。


步骤

首先,继承 NSTableRowView 并覆盖 drawSelectionInRect 以在选中时更改其背景颜色:

@implementation MyTableRowView

- (void)drawSelectionInRect:(NSRect)dirtyRect

    [super drawSelectionInRect:dirtyRect];
    [[NSColor yellowColor] setFill];
    NSRectFill(dirtyRect);

接下来,使用 rowViewForRow NSTableView 委托方法返回您的子类行视图:

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

    static NSString* const kRowIdentifier = @"MyTableRow";
    MyTableRowView* myRowView = [tableView makeViewWithIdentifier:kRowIdentifier owner:self];
    if (!myRowView) 
        myRowView = [[MyTableRowView alloc] initWithFrame:NSZeroRect];
        myRowView.identifier = kRowIdentifier;
    
    return rowView;

使用这种方法,您还可以轻松覆盖其他元素,例如分隔符颜色。为此,请在 NSTableRowView 子类中重写 drawSeparatorInRect 方法,如下所示:

- (void)drawSeparatorInRect:(NSRect)dirtyRect

    // Change the separator color if the row is selected
    if (self.isSelected) [[NSColor orangeColor] setFill];
    else [[NSColor grayColor] setFill];
    // Fill the seperator
    dirtyRect.origin.y = dirtyRect.size.height - 1.0;
    dirtyRect.size.height = 1.0;
    NSRectFill(dirtyRect);


资源

覆盖NSTableRowView 显示设置 https://developer.apple.com/reference/appkit/nstablerowview

NSTableview rowViewForRow 委托方法 https://developer.apple.com/reference/appkit/nstableviewdelegate/1532417-tableview

【讨论】:

这应该是答案。【参考方案2】:

首先将tableview选择高亮样式设置为

 NSTableViewSelectionHighlightStyleNone

然后在你的 tablView 委托中实现

tableView:shouldSelectRow:

在里面写下这段代码:

NSTableViewRow *row= [_mainTable rowViewAtRow:selectedRow makeIfNecessary:NO];
row.backgroundColor = [your color];
return YES;

也阅读这些 https://developer.apple.com/library/mac/documentation/Cocoa/Reference/NSTableViewDelegate_Protocol/index.html#//apple_ref/occ/intfm/NSTableViewDelegate/tableView:rowViewForRow:

选择样式 https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSTableView_Class/index.html#//apple_ref/occ/instp/NSTableView/selectionHighlightStyle

【讨论】:

对于 NSTableRowView 我需要设置 tableRowView.needsDisplay = YES 以确保视图在更改颜色后会被重绘。 你是如何取消选择的? 当被问及 NSTableView 时,为什么要提供 iOS 示例(UITableViewRow...UI* 仅适用于 iOS)? 现在不知道 abt 但在那时,您只需将 UI 更改为 NS,反之亦然,它就可以工作 这会使所有先前选择的行都着色。【参考方案3】:

这是为选定的行设置自定义颜色以及突出显示的文本颜色。输出应该是这样的,

在上面的截图中,我们正在做

将背景选择颜色设置为白色

添加圆角半径

将文本颜色更改为蓝色

添加蓝色描边颜色

您可以进行更多自定义,但此答案涵盖了上述几点。

1.从继承 NSTableRowView 开始

class CategoryTableRowView: NSTableRowView 

override func drawSelection(in dirtyRect: NSRect) 
    if selectionHighlightStyle != .none 
        let selectionRect = bounds.insetBy(dx: 2.5, dy: 2.5)
        NSColor(calibratedRed: 61.0/255.0, green: 159.0/255.0, blue: 219.0/255.0, alpha: 1.0).setStroke()
        NSColor(calibratedWhite: 1.0, alpha: 1.0).setFill()
        let selectionPath = NSBezierPath(roundedRect: selectionRect, xRadius: 25, yRadius: 25)
        selectionPath.fill()
        selectionPath.stroke()
    
  

2。在 NSTableViewDelegate 方法中返回自定义 CategoryTableRowView()

func tableView(_ tableView: NSTableView, rowViewForRow row: Int) -> NSTableRowView? 
      return CategoryTableRowView()

3.确保您的 ViewController 类中有 selectionHighlightStyle 常规

override func viewDidLoad() 
     super.viewDidLoad()
     self.tableView.selectionHighlightStyle = .regular

4.要设置 textColor,请创建 NSTableCellView 的子类

class CategoryCellView: NSTableCellView 

@IBOutlet weak var categoryTextField: NSTextField!

override var backgroundStyle: NSView.BackgroundStyle 
    willSet
        if newValue == .dark 
            categoryTextField.textColor = NSColor(calibratedRed: 61.0/255.0, green: 159.0/255.0, blue: 219.0/255.0, alpha: 1.0)
         else 
            categoryTextField.textColor = NSColor.black
        
    
  

覆盖backgroundStyle 属性并为文本设置所需的颜色。

注意:就我而言,我有一个自定义单元格,它有一个categoryTextField 插座。所以要设置我使用的文本颜色: categoryTextField.textColor = NSColor.black

5.在故事板中设置自定义类

我希望这会有所帮助。谢谢。

【讨论】:

对于 objc,您可以使用 override NSTableCellView.setBackgroundStyle: 根据选择调整行。见docs。

以上是关于NSTableRowView/NSTableCellView 如何为选定的行设置自定义颜色?的主要内容,如果未能解决你的问题,请参考以下文章