如何在 Interface Builder 中制作 NSTableRowView 的原型

How to prototype NSTableRowView in Interface Builder

我有一个 view-based NSTableView,我正在尝试自定义某些行的外观。

我明白我需要实现标题中提到的委托方法;但是我不确定该怎么做。

文档说:

You can use the delegate method tableView:rowViewForRow: to customize row views. You typically use Interface Builder to design and lay out NSTableRowView prototype rows within the table. As with prototype cells, prototype rows are retrieved programmatically at runtime. Implementation of NSTableRowView subclasses is entirely optional.

但是,与单元格不同,界面生成器中没有 NSTableRowView class,也不清楚如何设置 "prototype" 行视图。

我正在尝试这样的事情 (Swift 3):

func tableView(_ tableView: NSTableView, rowViewForRow row: Int) -> NSTableRowView?
{
    if (row % 4) == 0 {
        // .................................................. 
        // [ A ] SPECIAL ROW:

        if let rowView = tableView.make(withIdentifier: "SpecialRow", owner: self) as? NSTableRowView {

            rowView.backgroundColor = NSColor.gray()
            return rowView
        }
        else {
            return nil
        }

        // ^ Always returns nil (Because I don't know how
        // to setup the prototype in Interface Builder)
    }
    else{
        // ..................................................
        // [ B ] NORMAL ROW (No customization needed)

        return nil
    } 
}

我有类似的代码适用于 cells - 即 -tableView:viewForTableColumn:row:.

好的,显而易见的(?)解决方案有效:

  1. 在 Interface Builder 上,将普通 NSView 拖放到 table 中(它只会接受特定列中的拖放,不是 作为 table 视图的直接子项)。

  2. 转到刚刚删除的视图的身份检查器,并将其 Class 更改为 "NSTableRowView"。

  3. 因为在我的代码中设置 .backgroundColor 属性 不起作用,我改为使用 this solution 并添加一个框视图作为子视图,并在界面生成器。我必须在框和行视图之间设置自动布局约束,以便它会在运行时拉伸到行视图的实际大小。

(或者,我可以使用行视图的 wantsLayer 属性...)


更新: 事实证明,我在代码中使用的 backgroundColor 属性 在 NSTableRowView 中定义(NSView 没有这样的 属性,不像 UIView)。

但它也会被 table 视图的设置覆盖(即是否交替行),所以我应该用这种方法自定义它:

func tableView(_ tableView: NSTableView, didAdd rowView: NSTableRowView, forRow row: Int)
{
    if (row % 4) == 0 {
        rowView.backgroundColor = NSColor.controlAlternatingRowBackgroundColors()[1]
    }
    else{
        rowView.backgroundColor = NSColor.clear()
    }    
}

... 添加之后(其背景颜色由 table 视图配置)。

(顺便说一句,我毕竟不需要自定义行视图。至少不需要自定义背景颜色)