简体   繁体   English

为什么我的superview-with-subview在以模态方式呈现时会缩小(使用自动布局)?

[英]Why does my superview-with-subview shrink when presented modally (using Auto Layout)?

I have a view controller that owns a single custom view; 我有一个视图控制器拥有一个自定义视图; the custom view draws a game board using Core Graphics. 自定义视图使用Core Graphics绘制游戏板。 (No other subviews are involved.) (不涉及其他子视图。)

I set up Auto Layout constraints so that the game board fills its superview. 我设置了自动布局约束,以便游戏板填充其超级视图。 When I set the view controller as the root view controller, then the game board (and superview) fills the screen, as is my intention. 当我将视图控制器设置为根视图控制器时,游戏板(和superview)填充屏幕,这是我的意图。 However, when I present the view controller modally, the game board (and superview) shrinks to nothing/minimum, and the Auto Layout trace reports the layout is ambiguous. 但是,当我以模态方式呈现视图控制器时,游戏板(和superview)缩小到空/最小,并且自动布局跟踪报告布局不明确。

I wrote a simplified test case to illustrate the question. 我写了一个简化的测试用例来说明这个问题。

Here is my BoardViewController , which has a top-level view with a green background, but creates a single expansive subview with a red background. 这是我的BoardViewController ,它有一个绿色背景的顶级视图,但创建了一个红色背景的单个扩展子视图。 I'd like to see the screen all red when this view controller takes over: 当这个视图控制器接管时,我想看到屏幕都是红色的:

- (void)loadView
{
  UIView *mainView = [[UIView alloc] init];
  mainView.translatesAutoresizingMaskIntoConstraints = NO;
  mainView.backgroundColor = [UIColor greenColor];

  UIView *subView = [[UIView alloc] init];
  subView.translatesAutoresizingMaskIntoConstraints = NO;
  subView.backgroundColor = [UIColor redColor];

  [mainView addSubview:subView];
  self.view = mainView;

  NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(subView);
  NSArray *c1 = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[subView(>=10)]|"
                                                        options:0
                                                        metrics:nil
                                                          views:viewsDictionary];
  NSArray *c2 = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[subView(>=10)]|"
                                                        options:0
                                                        metrics:nil
                                                          views:viewsDictionary];
  [self.view addConstraints:c1];
  [self.view addConstraints:c2];
}

If I set this as my root view controller, then I see my nice red game board filling the screen. 如果我将它设置为我的根视图控制器,那么我会看到我漂亮的红色游戏板填满屏幕。 However, the game board shrinks to the minimum 10x10 square when I present the BoardViewController from a different RootViewController : 但是,当我从另一个RootViewController呈现BoardViewController时,游戏板缩小到最小10x10平方:

- (void)loadView
{
  UIView *rootView = [[UIView alloc] init];
  rootView.translatesAutoresizingMaskIntoConstraints = NO;

  UIButton *presentButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
  presentButton.translatesAutoresizingMaskIntoConstraints = NO;
  [presentButton setTitle:@"Present" forState:UIControlStateNormal];
  [presentButton addTarget:self
                    action:@selector(present:)
          forControlEvents:UIControlEventTouchUpInside];

  [rootView addSubview:presentButton];
  self.view = rootView;

  [rootView addConstraint:[NSLayoutConstraint constraintWithItem:presentButton
                                                       attribute:NSLayoutAttributeCenterX
                                                       relatedBy:NSLayoutRelationEqual
                                                          toItem:rootView
                                                       attribute:NSLayoutAttributeCenterX
                                                      multiplier:1.0
                                                        constant:0.0]];
  [rootView addConstraint:[NSLayoutConstraint constraintWithItem:presentButton
                                                       attribute:NSLayoutAttributeCenterY
                                                       relatedBy:NSLayoutRelationEqual
                                                          toItem:rootView
                                                          attribute:NSLayoutAttributeCenterY
                                                      multiplier:1.0
                                                      constant:0.0]];
}

- (void)present:(id)sender
{
  BoardViewController *bvc = [[BoardViewController alloc] init];
  [self presentViewController:bvc animated:YES completion:NULL];
}

I keep trying different Auto Layout rules, but no matter what I do, I can't get the game board to fill the screen when the view controller is presented modally. 我一直在尝试不同的自动布局规则,但不管我做什么,当视图控制器以模态方式呈现时,我无法让游戏板填满屏幕。 (At the same time I'm asking this question, I'm trying to get the runtime to tell me what it thinks is ambiguous. But I'm not very good this debugging yet, hence my question here.) (与此同时我问这个问题,我正试图让运行时告诉我它的想法是不明确的。但是我的调试还不是很好,因此我的问题在这里。)

After some investigation, it looks like when you push a modal view controller full screen, and the animation is complete, the presenting view controller along with its view is being removed from the view hierarchy. 在进行一些调查之后,看起来当您按下模态视图控制器全屏并且动画完成时,将从视图层次结构中移除呈现视图控制器及其视图。 As expected, the views constraints are being removed then. 正如预期的那样,视图约束正被删除。 Once you dismiss the modal view controller, the original viewcontroller with its view comes back again, but the constraints are gone and have not been saved and restored by the system. 一旦关闭模态视图控制器,原始视图控制器及其视图将再次返回,但约束已消失,系统尚未保存和恢复。 That is a bug. 那是一个错误。 Even on iOS7. 甚至在iOS7上。 The reason why using NSAutoresizingConstraints works is, that the view system is able to rebuild the constraints by itself. 使用NSAutoresizingConstraints的原因是,视图系统能够自行重建约束。

As a side note: if you have a setup with nested viewControllers (eg an outer viewcontroller embeds a navigation controller), then you can link these using the child viewcontrollers pattern. 作为旁注:如果您有嵌套viewcontrollers的设置(例如外部视图控制器嵌入导航控制器),那么您可以使用子视图控制器模式链接这些。 If you have done so, the topmost viewController view is being removed by what I described above. 如果您已经这样做了,最上面的viewController视图将被我上面描述的删除。 This means that you must only apply the NSAutoresizingConstraints patch to that topmost viewcontroller (typically the windows root viewcontroller) and use standard constraints wherever inbetween. 这意味着您必须仅将NSAutoresizingConstraints补丁应用于最顶层的viewcontroller(通常是windows根视图控制器),并在其间使用标准约束。

Remove: 去掉:

mainView.translatesAutoresizingMaskIntoConstraints = NO;

It's interesting that this works. 这很有意思。 It implies that when the view is presented modally using presentViewController it is expected to have constraints relating it to its superview, but when set as rootViewController of a UIWindow it doesn't need them... 这意味着当使用presentViewController以模态方式呈现视图时,它应该具有将其与其rootViewController相关联的约束,但是当设置为UIWindow rootViewController ,它不需要它们......

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么我的模态呈现(表单)navController的rootViewController不能以模态呈现时意识到它的尺寸较小? - Why isn't the rootViewController of my modally presented (form sheet) navController aware of it's smaller size when presented modally? 为什么以模态显示视图控制器会破坏表格视图中的“自动布局”? - Why does modally presenting a view controller break Auto Layout in my table view? 如何使子视图的位置变化与其父视图相关?使用情节提要的自动布局 - How to make subview's position change relate to its superview?Using storyboard's auto layout 为什么我的视图控制器(从故事板中以模态方式呈现)在被解雇后不会被释放? - Why does my view controller (presented modally from a storyboard segue) not get released after being dismissed? 旋转模态呈现的子视图控制器时,为什么我的约束不起作用? - Why are my constraints not working when rotating a modally presented child view controller? 更改子视图的高度后重新调整超级视图的大小-无自动布局 - Resize superview after changing height of subview - WITHOUT AUTO LAYOUT 当已经出现另一个模态时,“显示模态”不显示 - “Present Modally” does not show when another modal is already presented 在不使用自动布局的情况下呈现模态? - Present Modally without using auto layout? 以模态方式显示视图时是否调用viewDidDisappear - Does viewDidDisappear gets called when a view is presented modally 使用自动布局将子视图添加到另一个子视图 - Adding subview to another subview using Auto Layout
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM