2012-07-12 56 views
5

我在主應用程序菜單中有一個菜單項,我想將其操作路由到視圖控制器(NSViewController)。界面層次結構如下所示:有一個由NSWindowController組成的主應用程序窗口控制器。窗口內部有分割視圖,分割視圖中的右側視圖由NSViewController控制。如何將菜單動作路由到窗口內的NSViewController?

Window + NSWindowController 
    `-- NSSplitView 
      `-- NSView 
      `-- NSView + NSViewController 

菜單項連接到Interface Builder中的First Responder。所討論的視圖控制器實現了適當的方法,但菜單項保持禁用狀態。當我將該方法移動到NSWindowController時,菜單項被啓用。

我想我需要將視圖控制器鏈接到響應鏈,所以我將其設置爲窗口控制器的nextResponder;沒有雪茄。我究竟做錯了什麼?

+0

您可以在IB中添加一個對象,代表您的Controller。然後將菜單操作鏈接到控制器的IBAction。 – 2012-07-12 14:17:28

+0

不幸的是,這是不可能的,視圖控制器根據在左側分割視圖窗格中選擇的內容而改變。 – zoul 2012-07-12 14:19:14

+0

然後,每次視圖獲得焦點時,必須重新分配菜單操作。要訪問te菜單:[[[[[NSApp mainMenu] itemWithTitle:@「ItemName」] menu] itemWithTitle @「ItemName] setAction:@」Selector(theSelector)] – 2012-07-12 14:25:38

回答

3

最後,我添加了一個基類,我的窗控制器,並使其將呼叫轉移到「孩子」控制器:

- (id) childControllerForSelector: (SEL) selector 
{ 
    for (id controller in [childControllers copy]) 
     if ([controller respondsToSelector:selector]) 
      return controller; 
    return nil; 
} 

- (BOOL) respondsToSelector: (SEL) selector 
{ 
    return [super respondsToSelector:selector] ? YES : 
     [self childControllerForSelector:selector] ? YES : 
      NO; 
} 

- (void) forwardInvocation: (NSInvocation*) invocation 
{ 
    id child = [self childControllerForSelector:[invocation selector]]; 
    [invocation invokeWithTarget:child]; 
} 

- (NSMethodSignature*) methodSignatureForSelector: (SEL) selector 
{ 
    NSMethodSignature *signature = [super methodSignatureForSelector:selector]; 
    if (!signature) { 
     id child = [self childControllerForSelector:selector]; 
     signature = [child methodSignatureForSelector:selector]; 
    } 
    return signature; 
} 

這是一個很大的代碼,但它是保持控制器的通用解決方案代碼免於臨時轉發。希望這不是太神奇。

1

您可以將窗口控制器設置爲窗口的委託,以便它現在成爲響應者鏈的一部分。

假設您有自己的NSWindowController的子類,那麼您可以簡單地在那裏捕獲菜單事件並在您的控制器中調用適當的方法。

不幸的是,文檔建議反對試圖在各種視圖和子視圖之間的響應者鏈中插入任何東西,所以你不能只是擠壓你的視圖控制器在那裏。

更多here,但我認爲你已經諮詢過了。

相關問題