0

NSWindowControllerルート ビューを含む があります。ルートビューには 4 NSButtons、いくつかのテキストと画像があります。各ボタンは にバインドされていNSViewControllerます。ボタンの 1 つをクリックすると、ルート ビューが削除され、それにバインドされたビューNSViewController(サブビューと呼びましょう) が表示されます。サブビューにはNSButton、ウィンドウ コントローラに通知を送信してルート ビューを復元する があります。これが私のコードです(役に立たない部分のほとんどを削除しました)

  • 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のビューは削除されますが、ルート ビューは表示されません。

4

1 に答える 1

2

WindowController.hで宣言されvwRootたものと同じであり、すべてが正しくバインドされ、nilでないことを前提として、コードを再作成しました。viewRootテキストビューをターゲットビューと2つのボタンとして使用し、別のビュー(コントローラーが所有)に置き換えられている間、その参照を保持しました。

同じ問題が発生しましたが、自動レイアウトでのみ発生しました。自動レイアウトを無効にすると、コードが完全に機能し始めました。

問題は制約にありました。が削除さ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、制約はないはずです。したがって、それを修正するコードがない限り、ウィンドウのサイズを変更するときに、コンテンツビューは従うべきではありません。

于 2012-10-17T13:36:40.567 に答える