设备旋转时iOS更改自动布局约束

时间:2012-12-06 08:48:23

标签: objective-c ios autolayout nslayoutconstraint

我想在设备旋转时修改布局约束。 我的UIViewController由2 UIViews组成,在横向上它们是水平对齐的, 在纵向上,它们是垂直对齐的。

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

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

另一个问题是性能,经过几次旋转后系统不会再破坏约束,但是我的性能下降很大,特别是在纵向模式下......

3 个答案:

答案 0 :(得分:51)

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

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

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

答案 1 :(得分: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提交更改。

我希望它会有所帮助。

答案 2 :(得分:2)

覆盖-(void) viewWillLayoutSubviews中的UIViewController以更新您的约束,如下所示:

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

              break;
          case UIInterfaceOrientationLandscapeRight:

              break;

          case UIDeviceOrientationPortrait:

              break;

          case UIDeviceOrientationPortraitUpsideDown:

              break;

     }
}