Cocoa应用程序的故事板似乎是一个很好的解决方案,因为我更喜欢你在iOS中找到的方法.然而,虽然将事情分解为单独的视图控制器具有很多逻辑意义,但我不清楚如何将窗口控件(工具栏按钮)或菜单交互传递给关心的视图控制器.我的应用程序委托是第一个响应者,它接收菜单或工具栏操作,但是,如何访问我需要获取该消息的视图控制器?您可以深入查看视图控制器层次结构.如果是这样,你是如何从应用代表那里到达那里的,因为它是第一个响应者?你可以让窗口控制器成为第一响应者.如果是这样,怎么样?在故事板?哪里?
由于这是一个高级别的问题,因此,如果您想知道,我正在使用Swift进行此项目.
我不确定是否有“正确”的方法来解决这个问题,我已经提出了一个我现在将要使用的解决方案.首先是几个细节
>我的应用程序是基于文档的应用程序,因此每个窗口都有一个文档实例.
>应用程序使用的文档可以充当第一响应者并转发我已连接的任何操作
>该文档能够掌握顶级窗口控制器,从那里我可以向下钻取视图控制器层次结构,以获得我需要的视图控制器.
所以,在窗口控制器上的windowDidLoad中,我这样做:
override func windowDidLoad() { super.windowDidLoad() if self.contentViewController != nil { var vc = self.contentViewController! as NSSplitViewController var innerSplitView = vc.splitViewItems[0] as NSSplitViewItem var innerSplitViewController = innerSplitView.viewController as NSSplitViewController var layerCanvasSplitViewItem = innerSplitViewController.splitViewItems[1] as NSSplitViewItem self.layerCanvasViewController = layerCanvasSplitViewItem.viewController as LayerCanvasViewController } }
这让我获得了视图控制器(它控制下面用红色标出的视图)并在窗口视图控制器中设置一个本地属性.
现在,我可以直接在响应程序链中的文档类中转发工具栏按钮或菜单项事件,从而接收我在菜单和工具栏项中设置的操作.像这样:
class LayerDocument: NSDocument { @IBAction func addLayer(sender:AnyObject) { var windowController = self.windowControllers[0] as MainWindowController windowController.layerCanvasViewController.addLayer() } // ... etc. }
由于LayerCanvasViewController在加载时被设置为主窗口控制器的属性,我可以访问它并调用我需要的方法.