我有NSSplitView
来管理向下钻取的层次结构。父/左侧显示组,而子/右侧接收组选择已更改的通知,并更新以显示子项。
但是:使用故事板创建NSSplitView
时,会创建3个场景:一个用于拆分视图本身,另一个用于右/左NSViewController
实例
这里的问题是我有两个控制器也充当NSTableViewDataSource
个项目,父控制器应该有IBOutlet
个子< / em>控制器,以便它可以提供选择已更改的直接通知。
但是!因为这些控制器在不同的场景中,所以我无法连接它们。我也无法将它们移动到拆分视图的父场景,因为它们无法访问NSTableView
个出口。 (表也不会将控制器作为代理/数据源引用。)
我需要在这里使用NSNotification
吗?它看起来是间接的,多余的,我还没有在Mac上找到基于segue的方法。
答案 0 :(得分:11)
新的NSSplitViewController和NSTabViewController类是Apple称之为容器控制器的类。您可以使用NSViewController中的新属性
获取容器内其他控制器的引用@property (readonly) NSViewController *parentViewController
@property (copy) NSArray *childViewControllers
所以例如,如果您想从父表控制器获取对子Table控制器的引用。在父表控制器viewDidLoad中,您可以执行以下操作
myChildTableController = [self.parentViewController childViewControllers][1];
来自您的子表控制器的或反之亦然
myParentTableController = [self.parentViewController childViewControllers][0];
答案 1 :(得分:0)
正如你所说,OS X上的故事板(以及之前的iOS),不允许你在场景之间连接IBOutlet,所以你需要以其他方式传达动作。
我将在三个控制器中的任何一个的awakeFromNib
方法上配置actions / delegates属性。此时,NSSplitView
及其子控制器将全部创建并连接。
如果没有多个目标对象,或者目标对象已知且已修复,我将不会使用通知,如您的情况。
答案 2 :(得分:0)
您不一定要使用NSSplitViewController。相反,只需将NSSplitView拖动到Storyboard的主视图中即可。
正如Cory在他的回答中解释的那样,新的NSSplitViewController和NSTabViewController具有访问父控制器和子控制器的方法。如果您确实希望将界面划分为不同的Storyboard场景,这将非常有用。
在您的示例中,您希望所有视图都在同一场景中,以便您可以将所有IBOutlet连接到同一个视图控制器。所以,只需使用NSSplitView,根本不用担心NSSplitViewController。
答案 3 :(得分:0)
我遇到了同样的问题并找到了解决方法。它不是非常优雅,它不允许您使用故事板连接插座,但它确实允许您创建与IBOutlets
相同的关系。
关键是要实现一个单例类:
import Foundation
import Cocoa
class SplitViewConnector {
static let sharedInstance = SplitViewConnector()
var masterController:NSViewController?
var detailController:NSViewController?
}
现在,在主控制器的awakeFromNib
方法中,您可以设置主关系,同样,您可以为细节控制器设置关系。
例如,如果您的主控制器需要与您的详细控制器有直接关系,您也可以实现它。假设您的主控制器的类是YourViewController
并且用于访问您的详细信息控制器的属性被称为myDetail
,它将看起来像:
var masterController:YourViewController? {
didSet {
self.assignDirectConnections()
}
}
var detailController:NSViewController? {
didSet
self.assignDirectConnections()
}
}
func assignDirectConnections() {
if let master = self.masterController {
if let detail = self.detailController {
master.myDetail = detail
}
}
}