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

vit*_*ter 45 objective-c ios autolayout nslayoutconstraint

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

它实际上工作,在willAnimateRotationToInterfaceOrientation,我删除所需的约束,并将其替换为其他人,以获得正确的布局...

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

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

rob*_*off 51

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

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

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

  • 您是否必须对每个将修改其约束的视图进行子类化,或者您是否可以通过视图控制器以某种方式完成此操作?似乎一个非常非常常见的情况是改变旋转变化的一些宽度和高度,但如果你必须为许多内部视图填充多个自定义类的布局,那将会非常难看. (2认同)

Fla*_*lar 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;
}
Run Code Online (Sandbox Code Playgroud)

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

_leadingSpaceConstraint.constant = NEW_CONSTRAINT_VALUE;
Run Code Online (Sandbox Code Playgroud)

要提交更改,您需要致电:

[self.view layoutIfNeeded];
Run Code Online (Sandbox Code Playgroud)

如果你想做动画:

[UIView animateWithDuration:0.25
                 animations:^{
                     [self.view layoutIfNeeded];
                 }];
Run Code Online (Sandbox Code Playgroud)

我认为它将在willAnimateRotationToInterfaceOrientation中工作,因为你不需要用这种方法来破坏任何约束.

一些例子:你有两个纵向视图,一个在另一个下面.例如,将他们的"领先空间到超级视图"约束设置为20.然后将"top space to superview constraint"设置为20表示第一个视图,120表示第二个.这将是我们的默认设置.

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

我希望它会有所帮助.