设备旋转时 iOS 更改自动布局约束
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13739902/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
iOS change auto layout constraints when device rotates
提问by vitaminwater
I want to modify the layout constraints when the device rotates.
My UIViewController
is composed of 2 UIViews
, in landscape they are horizontally aligned,
and in portrait they are vertically aligned.
我想在设备旋转时修改布局约束。MyUIViewController
由 2 组成UIViews
,在横向中它们水平对齐,在纵向中它们垂直对齐。
It does work actually, in willAnimateRotationToInterfaceOrientation
, I remove the desired constraints and replaced them with others to have the right layout...
它确实有效,在willAnimateRotationToInterfaceOrientation
,我删除了所需的约束并用其他约束替换它们以获得正确的布局......
But there are problems, during rotation auto layout starts breaking constraints before willAnimateRotationToInterfaceOrientation
is called, so where are we meant to replace our constraints when the device reorientation occurs ?
但是有问题,在旋转期间自动布局在willAnimateRotationToInterfaceOrientation
调用之前开始打破约束,那么当设备重新定向发生时我们打算在哪里替换我们的约束?
Another issue is performance, after a few rotations the system doesn't break anymore constraints, but I have a huge performance drop, especially in portrait mode...
另一个问题是性能,经过几次旋转后,系统不再打破约束,但是我的性能下降了很多,尤其是在纵向模式下......
回答by rob mayoff
In willRotateToInterfaceOrientation:duration:
, send setNeedsUpdateConstraints
to any view that needs its constraints modified.
在 中willRotateToInterfaceOrientation:duration:
,发送setNeedsUpdateConstraints
到任何需要修改其约束的视图。
Alternatively, make a UIView
subclass. In your subclass, register to receive UIApplicationWillChangeStatusBarOrientationNotification
. When you receive the notification, send yourself setNeedsUpdateConstraints
.
或者,创建一个UIView
子类。在您的子类中,注册以接收UIApplicationWillChangeStatusBarOrientationNotification
. 当您收到通知时,请发送给您自己setNeedsUpdateConstraints
。
This sets the needsUpdateConstraints
flag on the view. Before the system performs layout (by sending layoutSubviews
messages), it sends an updateConstraints
message to any view that has the needsUpdateConstraints
flag set. This is where you should modify your constraints. Make a UIView
subclass and override updateConstraints
to update your constraints.
这会needsUpdateConstraints
在视图上设置标志。在系统执行布局(通过发送layoutSubviews
消息)之前,它会向updateConstraints
任何needsUpdateConstraints
设置了标志的视图发送一条消息。这是您应该修改约束的地方。创建一个UIView
子类并覆盖updateConstraints
以更新您的约束。
回答by Eugene Tartakovsky
There is very good explanation of auto-layout and rotations in Matthijs Hollemans post. You can find it here: http://www.raywenderlich.com/20881/beginning-auto-layout-part-1-of-2
Matthijs Hollemans 的帖子中对自动布局和旋转有很好的解释。你可以在这里找到它:http: //www.raywenderlich.com/20881/beginning-auto-layout-part-1-of-2
Usually, you need about 4 constraints to correctly position your view. If my views have constant size i prefer to pin height and width. After that you can use Leading and Top space constraints to do whatever you want. For example, you can set IBOutlets for leading and top space constraints for your views:
通常,您需要大约 4 个约束才能正确定位您的视图。如果我的视图大小不变,我更喜欢固定高度和宽度。之后,您可以使用 Lead 和 Top 空间约束来做任何您想做的事情。例如,您可以为视图的前导和顶部空间约束设置 IBOutlets:
@interface ViewController : UIViewController {
IBOutlet NSLayoutConstraint *_leadingSpaceConstraint;
IBOutlet NSLayoutConstraint *_topSpaceConstraint;
}
Then control-drag from outlet to your constraint. Now you can directly change your view constraint from code:
然后从出口控制拖动到您的约束。现在您可以直接从代码中更改您的视图约束:
_leadingSpaceConstraint.constant = NEW_CONSTRAINT_VALUE;
To commit your changes you need to call:
要提交您的更改,您需要调用:
[self.view layoutIfNeeded];
And if you want to do it animated:
如果你想做动画:
[UIView animateWithDuration:0.25
animations:^{
[self.view layoutIfNeeded];
}];
I think it will work in willAnimateRotationToInterfaceOrientation, because you don't need to break any constraints with this approach.
我认为它可以在 willAnimateRotationToInterfaceOrientation 中工作,因为您不需要用这种方法打破任何约束。
Some example: You have two square view in portrait orientation, one under another. Set their "leading space to superview" constraints to 20, for example. Then set "top space to superview constraint" to 20 for first view and to 120 for second. It will be our default setup.
一些例子:你有两个纵向的方形视图,一个在另一个下面。例如,将他们的“超视图前导空间”约束设置为 20。然后将第一个视图的“顶部空间到超级视图约束”设置为 20,第二个视图设置为 120。这将是我们的默认设置。
Then, after rotation you need to recalculate your constraints. Now set both of top constraints to 20, and leading constraints to 20 and 120 respectively. Then commit changes with layoutIfNeeded.
然后,在旋转之后,您需要重新计算约束。现在将两个顶部约束设置为 20,并将引导约束分别设置为 20 和 120。然后使用 layoutIfNeeded 提交更改。
I hope it will help.
我希望它会有所帮助。
回答by MuhammadBassio
override -(void) viewWillLayoutSubviews
in your UIViewController
to update your constraints as below code:
覆盖-(void) viewWillLayoutSubviews
您UIViewController
以更新您的约束,如下代码:
-(void) viewWillLayoutSubviews {
switch(self.interfaceorientation)
{
case UIInterfaceOrientationLandscapeLeft:
break;
case UIInterfaceOrientationLandscapeRight:
break;
case UIDeviceOrientationPortrait:
break;
case UIDeviceOrientationPortraitUpsideDown:
break;
}
}