我是一个iOS开发者,我正在创建我的第一个Mac应用程序。在尝试使用NSTableView时遇到了一些困难。
extension HomeViewController:NSTableViewDataSource{
func numberOfRows(in tableView: NSTableView) -> Int {
print(self.customerApplicationList.count) // '1' gets printed here
return self.customerApplicationList.count
}
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView?{
var result:NSTableCellView
result = tableView.make(withIdentifier: "firstName", owner: self) as! NSTableCellView
result.textField?.stringValue = "test"
return result
}
}

为什么里面没有显示值"test“的单元格?(在运行时,不包括这方面的屏幕快照)
发布于 2017-10-31 02:52:47
如果您在tableView(_:viewFor:row:)方法中添加了一个日志,您会发现它从未被调用过。你可能会想,这是为什么?嗯,这很复杂:
众所周知,AppKit不是使用Swift实现的,而是在Objective中实现的。object是一种非常动态的语言,它允许调用者查询对象是否响应某个消息,所以对象所要做的就是实现像-tableView:viewForTableColumn:row:这样的方法,并且通过object的魔力,AppKit可以找到该方法并调用它。使用Swift,情况要复杂一些,因为默认情况下,Swift方法不暴露于Objective,除非我们通过@objc关键字显式地使其公开,如果该方法是目标-C超类方法的覆盖,或者如果该方法满足Objective协议。第三种情况应该发生在这里,但事实证明,tableView(_:viewFor:row:)实际上属于NSTableViewDelegate,而不是NSTableViewDataSource。因此,Swift编译器并不认为您的方法满足任何协议,而且它没有暴露于目标-C。因此,从AppKit的角度来看,就好像根本没有实现它一样。
要解决当前问题,请将NSTableViewDelegate添加到扩展中,并确保将数据源设置为Interface中的委托。然而,在制作Mac应用程序时,我发现使用Cocoa绑定填充表视图比较容易,因为您可以“免费”获得许多功能,如按列进行自动排序、提前类型选择和选择管理。要做到这一点,请执行以下步骤:
1)确保对象上的数组属性同时使用@objc和dynamic关键字标记,并且数组中包含的类是NSObject子类,并且其相关属性也标记为@objc和dynamic。
class Thingy: NSObject {
@objc dynamic var name: String
init(name: String) { self.name = name }
}
class MyViewControllerThingy: NSViewController {
@objc dynamic var myArray: [Thingy] = [Thingy(name: "Foo"), Thingy(name: "Bar")]
}这确保了AppKit能够执行它的动态目标-C魔术,自动使这个属性符合KVO,所以我们不需要自己做(这是必要的,因为Cocoa绑定是建立在KVO之上的)。
2)在Interface Builder中设置数组控制器,并在绑定检查器中将Array Controller的“模型密钥路径”设置为属性的名称:

3)现在选择您的表视图,并在其绑定检查器中分别将其内容、选择索引和排序描述符绑定到arrangedObjects、selectionIndexes和sortDescriptors,为每个视图保留“模型键路径”空白:

4)在表视图的单元格中选择文本字段,转到其绑定检查器,并将其绑定到表单元格视图,使用objectValue.的模型键路径,然后使用要在单元格中查看的属性名称:

最后,选择表列并将其排序键设置为属性检查器( "Selector“字段)中的属性名称(”Selector“字段允许您自定义调用对象以对其排序的方法;我喜欢使用localizedStandardCompare:对字符串进行不区分大小写的排序,但对于大多数其他类型,您只需将其保留在默认情况下):

等等:

在Interface中,这看上去可能很麻烦,但在它的末尾,我们几乎没有代码就设置了整个表。此外,我们还为您的用户提供了一个非常流畅的UI,以及一些免费的功能,我最喜欢的是通过单击标题来自动排序:

这一点的伟大之处不仅在于您不必自己重新排序数组,而且它甚至不会扰乱原始数组的顺序;更改只是为了显示目的。这里的数组仍然是["Foo", "Bar"]。
NSArrayController的另一个非常酷的特性是它也将管理您的选择。例如,如果您的表视图是侧栏,则可以将右边的另一个视图绑定到数组控制器中的选定对象,这样您就可以轻松地实现诸如Mail.app的窗格查看器之类的东西,包括在用户同时选择多个对象时指定要使用的占位符。它真的很光滑。
https://stackoverflow.com/questions/47027017
复制相似问题