使用不带XIB的Cocoa绑定填充NSTableView或NSCollectionView

时间:2015-08-04 07:06:18

标签: objective-c macos swift cocoa

我想将NSTableViewNSCollectionView绑定到由NSArrayControllerNSArray属性组成的数据源。但是,我希望在代码中执行此操作,因为出于各种技术原因,我的UI中没有XIB。

由于Apple没有提供任何关于如何操作的文档,我正在寻找一个规范的答案,很好地表达了应该如何做到这一点。

如果答案是在Objective-C或Swift中,则无关紧要。

以下是不起作用

contactsTableView.bind(NSContentBinding,
    toObject: myViewModel,
    withKeyPath: "contacts",
    options: nil)

“contacts”是NSArrayController或带有字符串的NSArray。

1 个答案:

答案 0 :(得分:3)

您需要绑定到NSArrayController,而不仅仅是NSArray,因为您几乎肯定希望将通过数组元素绑定到其属性和NSArray不支持。绑定建立在Key-Value Observing之上,您无法通过数组或集合进行键值观察。

此外,阵列控制器通常是模型 - 视图 - 控制器中控制器层的一部分。因此,"联系"是不合理的。可以是命名myViewModel属性的关键路径,也可以是数组控制器。它应该是视图或窗口控制器的属性。

如果您的表视图基于NSCell,则通常应该绑定表列而不是表视图本身。表视图将根据其列的绑定自动绑定一些自己的绑定。如果要禁用该自动行为,则只能显式绑定表视图的绑定。

所以,你可以为每一栏做到:

[tableColumn bind:NSValueBinding toObject:self.contactsArrayController withKeyPath:@"arrangedObjects.propertyAppropriateToColumn" options:nil];

如果您的表视图是基于视图的,则应该绑定表视图的绑定而不是列。所以,你会这样做:

[contactsTableView bind:NSContentBinding toObject:self.contactsArrayController withKeyPath:@"arrangedObjects" options:nil];
[contactsTableView bind:NSSelectionIndexesBinding toObject:self.contactsArrayController withKeyPath:@"selectionIndexes" options:nil];
[contactsTableView bind:NSSortDescriptorsBinding toObject:self.contactsArrayController withKeyPath:@"sortDescriptors" options:nil];

如果表格单元格视图是NSTableCellView或子类,则表格视图会将其objectValue属性设置为数组中的相应元素。 NSTableCellView中的视图应使用objectValue.propertyAppropriateToThatView之类的关键路径绑定到它。如果您不使用NIB,则必须在-tableView:viewForTableColumn:row:委托方法中设置此绑定。你还必须拆除绑定,这会很难,因为表格视图在丢弃单元格视图时不会告诉你。它可能适用于-tableView:didAddRowView:forRow:中的设置和-tableView:didRemoveRowView:forRow:中的拆分,但那些不直接为您提供单元格视图。您需要自己将行视图中的单元格视图与表格列相关联。 (不难,只是单调乏味。)

如果表格单元格视图是响应-setObjectValue:的控件或其他视图,则表视图将调用该视图以将对象值设置为数组的元素。在这种情况下,您可能希望更改内容绑定以将通过 arrangedObjects转到数组元素的相关属性。

集合视图的情况类似于基于视图的表视图。您只能绑定NSContentBindingNSSelectionIndexesBinding;没有NSSortDescriptorsBinding,因为集合视图没有用户更改排序的界面(如表格列标题)。集合视图将每个集合视图项representedObject设置为数组的元素。项目视图或其子视图应通过representedObject绑定到项目,并绑定到元素的某个特定属性。

如果您没有使用NIB,那么您可能希望使用NSCollectionViewItem的自定义子类。这将在调用super之后在其-viewDidLoad方法(10.10或更高版本)或其-loadView方法中设置绑定。您可以在解除分配时拆除绑定。或者,您可以设置它们并在-viewWillAppear-viewWillDisappear中将其拆除。