使用Swift中的Bindings以编程方式创建基于NSTableView的视图

时间:2016-01-04 01:36:36

标签: swift nstableview cocoa-bindings nstablecolumn

我正在通过Swift书中的Cocoa工作,我被困在关于Bindings的章节中。本书使用nib文件,但我想以编程方式完成所有操作(因为我加入了一个不使用nib的团队)。该项目是创建一个包含2列的基于视图的表,表的内容绑定到数组控制器的 arrangeObjects 。数组控制器的内容绑定到Employee对象数组(Employee有2个属性,即名称和工资)。

我能够以编程方式创建表,如下所示(一个滚动视图,一个表视图,两个表列):

let tableWidth = windowWidth! * 0.6
let tableHeight = windowHeight! * 0.8

scrollView = NSScrollView(frame: NSRect(x: windowWidth!*0.05, y: windowHeight!*0.08, width: tableWidth, height: tableHeight))

employeeTable = NSTableView(frame: NSRect(x: 0, y: 0, width: tableWidth, height: tableHeight))
employeeTable?.bind("content", toObject: (self.arrayController)!, withKeyPath: "arrangedObjects", options: nil)

nameColumn = NSTableColumn(identifier: "name column")
nameColumn?.width = tableWidth * 0.4
nameColumn?.headerCell.title = "Name"

raiseColumn = NSTableColumn(identifier: "raise column")
raiseColumn?.width = tableWidth * 0.6
raiseColumn?.headerCell.title = "Raise"

employeeTable?.addTableColumn(nameColumn!)
employeeTable?.addTableColumn(raiseColumn!)
employeeTable?.setDelegate(self)

scrollView?.documentView = employeeTable

正如您所看到的,我不知道该表是基于单元格还是基于视图。我怎么知道我的桌子是基于什么的?由于本章是关于Bindings的,因此没有使用任何委托或数据源方法,我也想这样做。

下一个问题: 就像我说的那样,本书使用了NIB,可以随时访问NSTableView,NSTableCellView和它下面的NSTextField。首先,NSTableView的内容绑定到阵列控制器的arrangeObjects。我能够以编程方式执行此部分,因为我自己在代码中创建了tableView对象。然后,本书将NSTextField的值绑定到NSTableCellView的objectValue.name(name是Employee对象的属性之一)。我怎么做这部分,因为我没有在我的代码中创建这些NSTableCellView和NSTextField对象?有没有办法访问它们(假设我的表甚至是基于视图的)?

1 个答案:

答案 0 :(得分:4)

我正在回答我自己的问题。请注意,我是初学者,不知道这是否是正确的做事方式。正如用户stevesilva在上述问题的评论中所指出的,我必须实现委托方法tableView:viewForTableColumn:row:以确保表是基于视图的。在委托方法中,我尝试创建一个NSTableCellView并绑定textField属性,但这不起作用。我不得不继承NSTableCellView,创建一个新的文本字段属性,然后绑定该属性。这是我的代表最终看来的样子。

func tableView(tableView: NSTableView, viewForTableColumn tableColumn: NSTableColumn?, row: Int) -> NSView? {

    let frameRect = NSRect(x: 0, y: 0, width: tableColumn!.width, height: 20)

    let tableCellView = MyTableCellView(frame: frameRect)

    if tableColumn?.identifier == "name column" {
        tableCellView.aTextField?.bind("value", toObject: tableCellView, withKeyPath: "objectValue.name", options: nil)
    } else if tableColumn?.identifier == "raise column" {
        tableCellView.aTextField?.bind("value", toObject: tableCellView, withKeyPath: "objectValue.raise", options: nil)
    }

    return tableCellView
}

这是我的子类NSTableCellView:

class MyTableCellView: NSTableCellView {

    var aTextField: NSTextField?

    override init(frame frameRect: NSRect) {
        super.init(frame: frameRect)
        aTextField = NSTextField(frame: frameRect)
        aTextField?.drawsBackground = false
        aTextField?.bordered = false
        self.addSubview(aTextField!)
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

}