2012-10-17 2 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과 동일하고 모든 것이 올바르게 바인딩되고 nil이 아닌 것으로 가정하여 코드를 다시 작성했습니다. 필자는 텍스트보기를 대상보기, 두 개의 단추로 사용했으며 다른보기 (제어기 소유)로 대체되는 동안 참조를 유지했습니다.

동일한 문제가 발생했습니다 (). 자동 레이아웃은입니다. 자동 레이아웃을 비활성화하면 코드가 완벽하게 작동하기 시작합니다.

문제는 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을 켠 상태에서만 필요합니다. 그렇지 않으면 코드가 정상입니다. Autolayout은 Cocoa의 비교적 새로운 기능입니다. 그것을 사용하거나 사용하지 않는 것은 당신에게 달렸습니다 : 기본 인터페이스 만 있으면 사용할 수 없지만 설정이 매우 강력하고 빠르며 (작동 원리를 배울 때) 실제로 활용할 수 있습니다. 먼저 문서를 살펴보십시오. –