【问题标题】:NSTableRowView/NSTableCellView how to set custom color to selected row?NSTableRowView/NSTableCellView 如何为选定的行设置自定义颜色?
【发布时间】:2023-03-16 14:53:02
【问题描述】:

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

-(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 你有什么想法吗?
  • 您的问题已经得到解答。去这里stackoverflow.com/questions/11920156/…
  • @Rana Tallal 这是 Ios 的。
  • 您可以应用与 ios 相同的逻辑。将 selectionstyle 设置为 non,然后在选择时将颜色更改为您想要的颜色。并用动画改回来
  • @Rana Tallal,是的,我试过了,现在可以了。

标签: objective-c macos cocoa


【解决方案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
猜你喜欢
  • 2021-03-25
  • 2020-12-14
  • 2012-10-10
  • 2018-06-29
  • 1970-01-01
  • 2018-07-20
  • 2020-04-21
  • 1970-01-01
  • 2020-01-06
相关资源
最近更新 更多