对表格单元格视图中的NSTableView标识符感到困惑

时间:2017-01-05 18:01:57

标签: macos swift3 nstableview

我能够创建基于NSTableViews的简单视图,但有一点我不了解标识符。

在NSTableView中,您通常会为列提供标识符,然后实现委托方法:

func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView?

然后你打开专栏来做你需要的事情,比如:

switch tableColumn!.identifier {
case "firstColumn":
    //do something...
case "secondColumn":
    //do something else...
default:
    return nil
}

然而另外你也可以给每个表格单元格查看一个标识符。所以在上面的例子中,假设我没有给列添加标识符,而是给了< strong>表格单元格视图本身。

我认为那时我可以在委托方法中做这样的事情:

if let firstColumnCellView = tableView.make(withIdentifier: "firstColumnCell", owner: self) as? NSTableCellView {
    view.textField?.stringValue = "Hi! I'm in the first column"
    return view
} else if let secondColumnCellView = tableView.make(withIdentifier: "secondColumnCell", owner: self) as? NSTableCellView {
    view.textField?.stringValue = "Hi! I'm in the second column"
    return view
} else {
    return nil
}

这有效,但从未超过第一个if let语句,所以我的所有单元格都说“嗨!我在第一列”

更多信息:

我不明白的其他内容:似乎表格单元格视图标识符会覆盖列的标识符。

如果我转到文档大纲并指定如下标识符:

tableColumn: "firstColumn"
    tableViewCell: "firstColumnCell"

tableColumn: "secondColumn"
    tableViewCell: "secondColumnCell"

然后提供列标识符和单元格标识符,它可以工作!

 switch tableColumn!.identifier {
    case "firstColumn":
        if let firstColumnCellView = tableView.make(withIdentifier: "firstColumnCell", owner: self) as? NSTableCellView {
            view.textField?.stringValue = "Hi! I'm in the first column"
            return view
        } else {
            return nil
        }
    case "secondColumn":
        if let secondColumnCellView = tableView.make(withIdentifier: "secondColumnCell", owner: self) as? NSTableCellView {
            view.textField?.stringValue = "Hi! I'm in the second column"
            return view
        } else {
            return nil
        }
    default:
        return nil
    }

但如果我允许switch语句忽略第二列的单元格标识符,会崩溃,然后尝试使用列标识符。

 switch tableColumn!.identifier {
    case "firstColumn":
        if let firstColumnCellView = tableView.make(withIdentifier: "firstColumnCell", owner: self) as? NSTableCellView {
            view.textField?.stringValue = "Hi! I'm in the first column"
            return view
        } else {
            return nil
        }
    default:
        break
    }


    let cellView = tableView.make(withIdentifier: tableColumn!.identifier, owner: self) as! NSTableCellView
    cellView.textField?.stringValue = "hello"
    return cellView

    //CRASH: Unexpectedly found nil when unwrapping tableColumn!.identifier
    // The column both exists and has an identifier of "secondColumn", so how could
    //this be nil?

似乎我可以通过将secondColumnCell重命名为与secondColumn 相同的名称来确认这一重写行为:

tableColumn: "firstColumn"
    tableViewCell: "firstColumnCell"

tableColumn: "secondColumn" <--- Same Name
    tableViewCell: "secondColumn" <-- Same Name

现在代码按预期运行,不会崩溃。

1 个答案:

答案 0 :(得分:0)

如果我正确读取了您的最后一块代码,您可以实例化(或从 used-views-no-more-on-screen 池中检索 - 请参阅here)标识符 firstColumnCell

只要标识符有效(你有一个定义视图的nib),该方法将始终返回一个非零视图,因此第一个if let ...将始终成功。

因此view.textField?.stringValue = "Hi! I'm in the first column"将执行,从而在单元格中显示消息,然后它将返回NSTableView使用的视图并退出您的方法。

下一个if let ...语句永远不会有机会执行。