恢复以前删除的NSView

时间:2012-10-17 10:24:01

标签: objective-c macos cocoa

我有一个包含根视图的NSWindowController。根视图有4 NSButtons,一些文本和图像。每个按钮都绑定到NSViewController。当我单击其中一个按钮时,将删除根视图,并显示绑定到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的视图被删除,但根视图不会显示。

1 个答案:

答案 0 :(得分: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时,不应该有任何约​​束,所以除非您有一些代码来修复它,否则当您调整窗口大小时,您的内容观点不应该遵循。