0

我有一个NSWindowController包含根视图。根视图有 4 NSButtons,一些文本和图像。每个按钮都绑定到一个NSViewController. 当我单击其中一个按钮时,会删除根视图并显示绑定到NSViewController(我们称其为子视图)的视图。在子视图中,有一个NSButton向窗口控制器发送通知以恢复根视图。这是我的代码(我删除了大部分无用的部分)

  • 窗口控制器.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
    
  • 窗口控制器.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.hvwRoot中声明的相同viewRoot,并且所有内容都正确绑定且非零;我使用了一个文本视图作为目标视图、两个按钮,并在它被另一个视图(由控制器拥有)替换时保留了它的引用。

我遇到了同样的问题,但只有 autolayout。当我禁用自动布局时,代码开始完美运行。

问题出在约束中:当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 回答