iOS:如何为新的自动布局约束(高度)设置动画

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13296232/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 21:09:26  来源:igfitidea点击:

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

iosuiviewautolayoutnslayoutconstraint

提问by Meltemi

I've never worked with autolayoutconstraints 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 withit and try to figure out where Apple is going with this.

我以前从未使用过自动布局约束。我有一个正在开发的小型新应用程序,并注意到 NIB 的视图默认为自动布局。所以,我想我会借此机会它合作,并试图弄清楚 Apple 在这方面的发展方向。

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:

我需要调整 MKMapView 的大小,我想将其动画化到新位置。如果我按照我习惯的方式这样做:

[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]).

...然后,每当同级视图更新时,MKMapView 将“快速”恢复到其原始高度(在我的情况下,UISegmentedControl 的标题正在更新[myUISegmentedControl setTitle:newTitle forSegmentAtIndex:0])。

So, what I thinkI 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 wascovering: V:[MKMapView]-(16)-[UISegmentedControl]

所以,我觉得我想要做的是从等于父视图的HIGHT到可相对于UISegmentedControl,它的顶部改变的MKMapView的限制覆盖: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 thinkI 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.

我想要的是缩短 MKMapView 的高度,以便显示地图视图下方的一些控件。为此,我认为我需要将约束从固定的全尺寸视图更改为底部被约束到 UISegmentedControl 顶部的约束......并且我希望它在视图缩小到新大小时进行动画处理。

How does one go about this?

如何解决这个问题?

Edit - this animation is notanimatingthough the bottom of the view does move up 170 instantly:

编辑 -尽管视图底部确实立即向上移动了 170,但此动画并没有动画

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

    }];

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

并且nibMapViewConstraint在 IB 中连接到底部垂直空间约束。

回答by Ed McManus

After updating your constraint:

更新约束后:

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

Replace self.viewwith a reference to the containing view.

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

回答by DevC

This works for me (Both iOS7 and iOS8+). Click on the auto layout constraint you would like to adjust (in interface builder e.g top constraint). Next make this an IBOutlet;

这对我有用(iOS7 和 iOS8+)。单击要调整的自动布局约束(在界面构建器中,例如顶部约束)。接下来将其设为 IBOutlet;

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

Animate upwards;

向上动画;

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

Animate back to original place

动画回到原来的地方

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

回答by Glenn

There is a very good tutorial from apple itself that explain how to use animation with autolayout. Follow this linkand then find the video named "Auto layout by example" It gives some interesting stuff about autolayout and the last part is about how to use animation.

苹果本身有一个很好的教程,解释了如何在自动布局中使用动画。点击此链接,然后找到名为“通过示例自动布局”的视频。它提供了一些有关自动布局的有趣内容,最后一部分是关于如何使用动画。

回答by Jens Schwarzer

I have made this small demo available. It shows how auto-layout constraints can be changed and animated in a very simple example. Simply take a look at the DemoViewController.m.

我已经提供了这个小演示。它展示了如何在一个非常简单的示例中更改和动画自动布局约束。只需看看DemoViewController.m

回答by Arjay Waran

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

大多数人使用自动布局在他们的视图上布局项目并修改布局约束以创建动画。

An easy way to do this without a lot of code is creating the UIView you want to animate in Storyboard and then creating a hidden UIView where you want the UIView to end. You can use the preview in xcode to make sure both UIViews are where you want them to be. After that, hide the ending UIView and swap the layout constraints.

在没有大量代码的情况下,一种简单的方法是创建您想要在 Storyboard 中设置动画的 UIView,然后创建一个隐藏的 UIView,您希望 UIView 结束。您可以使用 xcode 中的预览来确保两个 UIView 都在您想要的位置。之后,隐藏结束的 UIView 并交换布局约束。

There is a podfile for swapping layout constrains called SBP if you don't want to write it yourself.

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

Here's a tutorial.

这是一个教程

回答by keshav vishwkarma

No need to use more IBOutlet referenceof the constraint instead of this you can directly accessor updatealready applied constraint either applied by Programmaticallyor from Interface Builderon any view using the KVConstraintExtensionsMasterlibrary. This library is also managing the Cumulativebehavior of NSLayoutConstraint.

无需使用更多IBOutlet reference约束,您可以直接accessupdate已经应用约束,无论是通过使用库的任何视图应用Programmatically还是从Interface Builder任何视图应用KVConstraintExtensionsMaster。该库还管理Cumulative的行为NSLayoutConstraint

To add Height Constraint on containerView

在 containerView 上添加高度约束

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

To update Height Constraint of containerView with animation

使用动画更新 containerView 的高度约束

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

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