iOS: How does one animate to new autolayout constraint (height)

I've never worked with autolayout constraints before. I have a small new app I'm working on and noticed that the NIB's views are defaulting to autolayout. So, I figured I'd take the opportunity to work with it and try to figure out where Apple is going with this.

First challenge:

I need to resize an MKMapView and I'd like to animate it to the new position. If I do this the way I'm used to:

[UIView animateWithDuration:1.2f
animations:^{
CGRect theFrame = worldView.frame;
CGRect newFrame = CGRectMake(theFrame.origin.x, theFrame.origin.y, theFrame.size.width, theFrame.size.height - 170);
worldView.frame = newFrame;
}];

...then the MKMapView will 'snap' back to its original height whenever a sibling view gets updated (in my case a UISegmentedControl's title is being updated [myUISegmentedControl setTitle:newTitle forSegmentAtIndex:0]).

So, what I think I want to do is change the constraints of the MKMapView from being equal to the parent view's hight to being relative to the top of the UISegmentedControl that it was covering: V:[MKMapView]-(16)-[UISegmentedControl]

What I want is for the MKMapView height to shorten so that some controls beneath the map view are revealed. To do so I think I need to change the constraint from a fixed full size view to one where the bottom is constrained to the top of a UISegmentedControl...and I'd like it to animate as view shrinks to new size.

How does one go about this?

Edit - this animation is not animating though the bottom of the view does move up 170 instantly:

    [UIView animateWithDuration:1.2f
animations:^{
self.nibMapViewConstraint.constant = -170;


}];

and the nibMapViewConstraint is wired up in IB to the bottom Vertical Space constraint.

82876 次浏览

更新约束后:

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

用对包含视图的引用替换 self.view

有一个非常好的教程从苹果本身,解释如何使用自动布局动画。 按照这个 链接,然后找到名为“自动布局示例”的视频 It gives some interesting stuff about autolayout and the last part is about how to use animation.

我做了 这个小演示可用。它在一个非常简单的示例中展示了如何更改自动布局约束并对其进行动画处理。简单地看一下 DemoViewController.m

这对我很有用(iOS7和 iOS8 +)。点击你想要调整的自动布局约束(Interface Builder 如顶部约束)。接下来,使这个 IBOutlet;

@property (strong, nonatomic) IBOutlet NSLayoutConstraint *topConstraint;

动画向上;

    self.topConstraint.constant = -100;
[self.viewToAnimate setNeedsUpdateConstraints];
[UIView animateWithDuration:1.5 animations:^{
[self.viewToAnimate layoutIfNeeded];
}];

动画回到原来的地方

    self.topConstraint.constant = 0;
[self.viewToAnimate setNeedsUpdateConstraints];
[UIView animateWithDuration:1.5 animations:^{
[self.viewToAnimate layoutIfNeeded];
}];

Most people use autolayout to layout items on their views and modify the layout constrains to create animations.

一个不需要大量代码的简单方法是在情节串连板中创建您想要动画化的 UIView,然后在您想要 UIView 结束的地方创建一个隐藏的 UIView。您可以使用 xcode 中的预览来确保两个 UIView 都位于您希望它们位于的位置。然后,隐藏结束的 UIView 并交换布局约束。

如果您不想自己编写,有一个称为 SBP 的 podfile 用于交换布局约束。

Here's a tutorial.

不需要使用更多的 IBOutlet reference的约束来代替这个约束,您可以直接 accessupdate已经应用的约束,或者由 Programmatically或从 Interface Builder应用到任何使用 KVConstraintExtensionsMaster库的视图上。这个库还管理 NSLayoutConstraintCumulative行为。

在容器视图上添加高度约束

 CGFloat height = 200;
[self.containerView applyHeightConstrain:height];

使用动画更新容器视图的高度约束

[self.containerView accessAppliedConstraintByAttribute:NSLayoutAttributeHeight completion:^(NSLayoutConstraint *expectedConstraint){
if (expectedConstraint) {
expectedConstraint.constant = 100;


/* for the animation */
[self.containerView  updateModifyConstraintsWithAnimation:NULL];
}
}];