面向列的NSTable中的对象数据

时间:2017-01-31 06:09:36

标签: swift macos nstableview

我正在尝试使用来自对象数组但面向列的信息填充我的NSTable。默认表格方向是按行。因此,每个对象信息都按行显示:

row oriented object data in NSTableView

但我需要按列显示对象信息:

column oriented object data in NSTableView

我不明白如何实现这一目标。如果列数在运行时是可变的以及如何显示面向对象数据列,该怎么办?重复使用单元格/视图的标准NSDataSourceProtocol在我的情况下无用:

func tableView(_ tableView: NSTableView, objectValueFor tableColumn: NSTableColumn?, row: Int) -> Any? {

  var text: String = ""
  var cellIdentifier: String = ""

  guard let item = modelObjectArray?[row] else {
    return nil
  }

   if tableColumn == tableView.tableColumns[0] {
     let text = item.name
     cellIdentifier = "someIdentifier"
    } else if ...{
       ...
    }

   if let cell = tableView.make(withIdentifier: cellIdentifier, owner: nil) as? NSTableCellView {
     cell.textField?.stringValue = text
     return cell
   }
return nil
}

有什么想法吗?

谢谢!

1 个答案:

答案 0 :(得分:1)

我同意评论说你最好选择不同的架构(UICollectionView确实是最好的选择)但是为了好玩,让我们尝试实现你的原始请求。

我已经做了很多假设来简化代码(就像所有的功能都是字符串一样)所以如果你想要它,你应该适应你的实现细节。

所以,首先让我们为你的表创建一个合适的模型(在你的viewDidLoad方法或类似的地方):

var feat1s = [String]()
var feat2s = [String]()
var feat3s = [String]()

for modelObject in modelObjects {
    feat1s.append(modelObject.feat1)
    feat2s.append(modelObject.feat2)
    feat3s.append(modelObject.feat3)    
}

然后,确保为每个行/列组合返回正确的对象:

func tableView(_ tableView: NSTableView, objectValueFor tableColumn: NSTableColumn?, row: Int) -> Any? {

    let colIndex = tableView.tableColumns.index(of: tableColumn!)!
    switch row {
        case 0: return feat1s[colIndex]
        case 1: return feat2s[colIndex]
        case 2: return feat3s[colIndex]
        default: return nil
    }
}

请注意,我们的数据源方法是返回String对象而不是NSTableCellView。它更容易在Interface Builder中使用绑定来链接"返回的对象到单元格视图模板中的字段。

如果您绝对想要返回完全格式化的NSTableCellView,我宁愿使用其他数据源方法:

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

现在,如果您有固定数量的模型对象(因此具有固定数量的列),则此方法有效。如果您事先不知道,可以使用数组字典而不是feat1sfeat2s等,并动态插入新列,例如

tableView.addTableColumn(tableColumn: NSTableColumn)