一个窗口中跨多个视图控制器的 Cocoa 绑定
Posted
技术标签:
【中文标题】一个窗口中跨多个视图控制器的 Cocoa 绑定【英文标题】:Cocoa binding across multiple view controllers in a window 【发布时间】:2014-10-30 07:02:03 【问题描述】:我正在努力解决在单独文件中的视图控制器之间使用 Cocoa 绑定的案例。 我检查了一些链接以获得灵感,但仍然没有。我觉得最好发一个 问题并让我休息一下......
类似主题: Binding selection across multiple view controllers in a single window interface
Sharing an NSArrayController between multiple views in separate NIB files
我有一个主控制器MainViewController.m/.h/.xib
和两个自定义视图。
还有一个单独的视图控制器SecondViewController.m/.h/.xib
。它的 xib 基本上包含一个表视图,以及一个绑定到表视图列的 ArrayController。这适用于绑定和选择等。
现在回到我的主控制器,我想从SecondViewController
访问表视图的选择索引。
到目前为止我的尝试
在我的主 XIB 中,我在 IB 中创建了一个 ViewController,并将自定义类和 nib 文件设置为 SecondViewController
。
在SecondViewController
的 XIB 中创建了一个 ArrayController,其 contentArray 设置为 KVC 列表属性“lists”。如上所述,这会在表格视图中正确显示内容。
问:如何在 MainViewController 中设置绑定,以便可以访问在 SecondViewController
中选择的对象?因为我想从我的主视图控制器中将该对象的详细信息绘制为子视图。一种在 Cocoa 教程中描述的主从界面。
【问题讨论】:
在 MainVC 中创建一个指向 SecondVC 实例的 secondVC 出口。在 SecondVC 中有一个指向 SecondVC 中的表视图的 tableView 出口。在 MainVC 中,使用 secondVC.tableView.selectionIndex 的键路径...对吗?那是很普通的东西,所以我想知道你是否想做一些更复杂的事情。 嗯,也许这很容易。所以你的意思是我需要在 secondVC 中的 tableview 插座以便稍后在我的 mainvc 中公开它?顺便说一句,没有 selectionIndex,只有 selectedRowIndexes - 这就是你的意思? 是的,语义。但是只要您的 MainVC 做一些工作来跟踪 secondVC 实例(避免使用 nil 指针),我不明白为什么您不能通过分层键路径进行绑定。 @stevesliva 我在一个沙盒项目中试过这个,mainVC 中的一个阵列控制器和第二个阵列控制器通过插座连接。我得到的只是表视图行中的左括号,用于通过插座(来自第二个 vc)连接的阵列控制器。主阵列控制器没问题。 我认为您不应该绑定或观察selectedRowIndexes
- 这是NSTableView
属性。可能,您应该设置并注意对 NSArrayController
的 Selection Indexes 绑定的更改,为您的第二个表格视图提供内容(请参阅下面的答案)。
【参考方案1】:
如果您想使用 Key-Value Observing 让您的 MainViewController
了解您的 SecondViewController
管理的表中所选行的更改,我认为最好的方法是是为NSArrayController
绑定Selection Indexes
设置一个值(这是为您的第二个表格视图提供内容的数组控制器)。
在您的 SecondViewController
类文件中添加如下属性:
@property (nonatomic, copy) NSIndexSet *secondTableSelectedIndexes;
现在在SecondViewController.xib
中选择相关的绿色NSArrayController
立方体,导航到它的绑定检查器并设置Selection Indexes
绑定以引用您刚刚创建的索引集属性。这是一个读写绑定。您可能永远不会自己在代码中编写它(尽管您可以根据需要),但是每次您在 SecondViewController
-managed 表中选择一个新行时,该索引集都会自动更新,因此,您需要使用这个属性会观察的。
要设置观察者,无论您可以访问两个视图控制器,添加以下内容:
/* Have my main view controller watch for selection changes in my
* second view controller's table
*/
self.secondViewController = [[SecondTableViewController alloc] initWithNibName:@"SecondTableViewController" bundle:nil];
[self.secondViewController addObserver:self.mainViewController
forKeyPath:@"secondTableselectedIndexes"
options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionPrior
context:nil];
然后可以通过在MainViewController
中实现-observeValueForKeyPath:ofObject:change:context:
来获取对secondTableSelectedIndexes
的更改。
【讨论】:
好的,我会尝试将其用于选择索引。但是将正确的字符串放入表格视图的问题仍然存在,仍然显示“(” 哪个表视图?您的SecondTableViewController
xib 中有一个表格视图,MainViewController
中是否也有一个?如果您希望MainViewController
与第二个视图控制器中的选择保持同步,则无需弄乱选择索引。一旦你明确了表视图的数量,我就可以解释绑定了。
我已经在一个沙盒项目中用简单的字符串数组进行了尝试。在我的 mainvc 中,我有两个数组控制器和一个包含两列的表视图。第一列绑定到 mainarraycontroller.arrangedObjects。第二列绑定到 secondarraycontroller.arrangedObjects。 SecondArrayController 的 contentArray 绑定到 self.secondViewController.tableArray(secondViewController 是一个 IBOutlet 属性)。第一列很好,第二列显示“(”。
一个数组控制器为两个表提供数据的情况并不少见,但我没有遇到使用两个数组控制器为一个表提供内容的情况。我不确定这应该如何工作,我很想说你应该重新考虑一下——尽管我很欣赏它可能完全有可能让它工作。对于这个特定的设置,我无能为力。
好吧,两个阵列控制器的唯一目的是方便调试,我想我想多了。如果我禁用了第一列的绑定,它可以很好地显示来自第二个视图控制器的内容。谢谢!也接受您的回答,因为我现在可以在我的主 vc 中观察 selectionIndexes。下一步是对选择采取行动!以上是关于一个窗口中跨多个视图控制器的 Cocoa 绑定的主要内容,如果未能解决你的问题,请参考以下文章