2012-10-17 76 views
0

我有一個NSWindowController它包含根視圖。根視圖有4 NSButtons,一些文字和圖像。每個按鈕都綁定到NSViewController。當我點擊其中一個按鈕時,根視圖被刪除,並且視圖被綁定到NSViewController(我們稱之爲子視圖)。在子視圖中,有一個NSButton,它向窗口控制器發送通知以恢復根視圖。這裏是我的代碼(我刪除了大部分的無用部分)恢復之前刪除的NSView

  • WindowController.h

    @interface MainWindowController : NSWindowController { 
    
    IBOutlet NSView* myTargetView; // bound to the whole view of the window 
    NSView*    viewRoot; 
    NSViewController* myCurrentViewController; 
    } 
    
    - (IBAction)buttonClicked:(id)sender; // Not shown in the implementation 
    - (void)changeViewController:(NSInteger)buttonTag; 
    - (void)restoreRootView; 
    
    @end 
    
  • WindowController.m

    - initWithPath:(NSString *)newPath 
    { 
        return [super initWithWindowNibName:@"MainWindow"]; 
    } 
    
    - (void)windowDidLoad { 
    
        vwRoot = [[[[self window] contentView] subviews] objectAtIndex:0]; 
    
        // set up notification observer, will call restoreRootView when receiving notification from NSViewController object 
    } 
    
    - (void)changeViewController:(NSInteger)buttonTag 
    { 
    
        [vwRoot retain]; 
    
        [vwRoot removeFromSuperview]; 
    
    
        if (myCurrentViewController != nil) 
        [myCurrentViewController release]; 
    
    switch (buttonTag) 
    
         { 
         case kView1: 
          { 
           View1Controller * viewOneController = [[View1Controller alloc]   initWithNibName:kViewOneTile bundle:nil]; 
    
         if (viewOneController != nil) { 
    
           myCurrentViewController = viewOneController; 
          } 
    
         break; 
         } 
    
         case kView2: 
         { 
    
          // and so on... 
    
         } 
        } 
    
    
        [myTargetView addSubview: [myCurrentViewController view]]; 
    
        [[myCurrentViewController view] setFrame: [myTargetView bounds]]; 
    
    } 
    
    
    - (void)restoreRootView { 
    
    
        [[myCurrentViewController view] removeFromSuperview]; 
    
        [myTargetView addSubview:vwRoot]; 
    
        [[vwRoot setFrame:[myTargetView bounds]]; 
    } 
    

不幸的是,當restoreRootView被調用, NSViewController的視圖被刪除,但不顯示根視圖。

回答

2

我重新創建了代碼,假設vwRoot與WindowController.h中聲明的viewRoot相同,並且所有內容都是正確綁定的而非零;我使用了一個文本視圖作爲目標視圖,兩個按鈕,並在被另一個視圖(由控制器擁有)替換時保留其引用。

我遇到了同樣的問題但只有自動佈局。當我禁用自動佈局時,代碼開始正常工作。

問題在於約束:當vwRoot被刪除時,定義其在myTargetView中的位置的約束被刪除。你必須再次定義它們,否則你的視圖將被放置在可見區域之外的地方(在我的情況下,窗口左下角的左上角:因此,沒有任何可見的東西)。

添加約束的代碼(設定框架是不必要的):

[myTargetView addSubview:vwRoot]; 
[vwRoot removeConstraints:vwRoot.constraints]; // eventually remove old w/h constraints 

// snap to left and right border 
[myTargetView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[vwRoot]-0-|" 
                    options:0 
                    metrics:nil 
                     views:NSDictionaryOfVariableBindings(vwRoot)]]; 

// snap to top and bottom border 
[myTargetView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[vwRoot]-0-|" 
                    options:0 
                    metrics:nil 
                     views:NSDictionaryOfVariableBindings(vwRoot)]]; 

應同樣適用於- (void)changeViewController:(NSInteger)buttonTag:當你添加myCurrentViewController.view,不應該有到位的任何約束,所以除非你有一些代碼來解決這個問題,當你調整窗口大小時,你的內容視圖不應該遵循。

+0

取消選中「使用自動佈局」修復它,謝謝!關於約束代碼,我只需要在自動佈局打開時添加它,對嗎?我應該不使用自動佈局? – b1onic

+0

是的,只有當您保留自動佈局時才需要,否則您的代碼就可以。 Autolayout是Cocoa中一個相對較新的功能;使用它與否取決於你:如果你只需要一個基本的界面,你可以禁用它,但是它的強大和快速設置(當你瞭解它的工作原理時),你可以真正利用它。所以先看一下文檔。 –