我想在设备旋转时修改布局约束。
我的UIViewController
由2 UIViews
组成,在横向上它们是水平对齐的,
在纵向上,它们是垂直对齐的。
它确实有效,在willAnimateRotationToInterfaceOrientation
中,我删除了所需的约束,并将其替换为其他约束以获得正确的布局......
但是有一些问题,在旋转期间自动布局在调用willAnimateRotationToInterfaceOrientation
之前开始打破约束,那么在设备重定向发生时我们在哪里替换我们的约束?
另一个问题是性能,经过几次旋转后系统不会再破坏约束,但是我的性能下降很大,特别是在纵向模式下......
答案 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;
}
}