48

我想在设备旋转时修改布局约束。MyUIViewController由 2 组成,UIViews横向对齐,纵向对齐。

它确实有效,在中willAnimateRotationToInterfaceOrientation,我删除了所需的约束并用其他约束替换它们以获得正确的布局......

但是有问题,在旋转期间自动布局在willAnimateRotationToInterfaceOrientation被调用之前开始打破约束,那么当设备重新定向发生时我们打算在哪里替换我们的约束?

另一个问题是性能,经过几次旋转后,系统不再打破限制,但我的性能下降很大,尤其是在纵向模式下......

4

3 回答 3

55

willRotateToInterfaceOrientation:duration:中,发送setNeedsUpdateConstraints到需要修改其约束的任何视图。

或者,创建一个UIView子类。在您的子类中,注册接收UIApplicationWillChangeStatusBarOrientationNotification。当您收到通知时,请发送给您自己setNeedsUpdateConstraints

这会needsUpdateConstraints在视图上设置标志。在系统执行布局(通过发送layoutSubviews消息)之前,它会向updateConstraints任何needsUpdateConstraints设置了标志的视图发送消息。这是您应该修改约束的地方。创建一个UIView子类并覆盖updateConstraints以更新您的约束。

于 2013-04-25T07:31:54.540 回答
13

在 Matthijs Hollemans 的帖子中对自动布局和旋转有很好的解释。你可以在这里找到它: http ://www.raywenderlich.com/20881/beginning-auto-layout-part-1-of-2

通常,您需要大约 4 个约束来正确定位您的视图。如果我的视图大小不变,我更喜欢固定高度和宽度。之后,您可以使用前导和顶部空间约束来做任何您想做的事情。例如,您可以为视图的前导和顶部空间约束设置 IBOutlets:

@interface ViewController : UIViewController {
    IBOutlet NSLayoutConstraint *_leadingSpaceConstraint;
    IBOutlet NSLayoutConstraint *_topSpaceConstraint;
}

然后从出口控制拖动到您的约束。现在您可以直接从代码中更改视图约束:

_leadingSpaceConstraint.constant = NEW_CONSTRAINT_VALUE;

要提交您的更改,您需要调用:

[self.view layoutIfNeeded];

如果你想做动画:

[UIView animateWithDuration:0.25
                 animations:^{
                     [self.view layoutIfNeeded];
                 }];

我认为它将在 willAnimateRotationToInterfaceOrientation 中起作用,因为您不需要使用这种方法打破任何约束。

一些例子:你有两个纵向的方形视图,一个在另一个下面。例如,将他们的“超级视图的前导空间”约束设置为 20。然后将“top space to superview constraint”设置为第一个视图的 20 和第二个视图的 120。这将是我们的默认设置。

然后,旋转后,您需要重新计算约束。现在将两个顶部约束设置为 20,将前导约束分别设置为 20 和 120。然后使用 layoutIfNeeded 提交更改。

我希望它会有所帮助。

于 2013-04-25T07:21:57.953 回答
2

覆盖-(void) viewWillLayoutSubviewsUIViewController以更新您的约束,如下代码:

-(void) viewWillLayoutSubviews {
     switch(self.interfaceorientation)
     {
          case UIInterfaceOrientationLandscapeLeft:

              break;
          case UIInterfaceOrientationLandscapeRight:

              break;

          case UIDeviceOrientationPortrait:

              break;

          case UIDeviceOrientationPortraitUpsideDown:

              break;

     }
}
于 2013-02-06T08:12:55.090 回答