如何为具有约束的 UIView 设置动画?

Posted

技术标签:

【中文标题】如何为具有约束的 UIView 设置动画?【英文标题】:How to animate a UIView that has constraints? 【发布时间】:2017-09-10 18:56:50 【问题描述】:

我有两个UIViews 我想在屏幕上和关闭动画。两者都应该开始定位在屏幕外。顶部向下动画,底部向上动画。没有约束,它按预期工作。但是,UIViews 在应用程序启动时可见(带有可见的轻微动画)。不过,它们确实会在屏幕外制作动画。

对于顶部UIView,我有一个前导空格、尾随空格、顶部空格和高度。

对于底部UIView,我有一个前导空格、尾随空格、底部空格和高度。

我应该如何调整我的代码和/或约束以获得所需的动画?

这是我的代码:

- (void)viewDidLoad 
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.


- (void)viewDidAppear:(BOOL)animated 
    [super viewDidAppear:animated];
    [self animateViewsIn];


- (void)viewWillLayoutSubviews 
    [super viewWillLayoutSubviews];

    self.topView.frame = CGRectMake(16.0, -self.topView.frame.size.height, self.topView.frame.size.width, self.topView.frame.size.height);

    self.bottomView.frame = CGRectMake(16.0, self.view.bounds.size.height, self.bottomView.frame.size.width, self.bottomView.frame.size.height);


- (void)didReceiveMemoryWarning 
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.


- (void)animateViewsIn 
    [UIView animateWithDuration:0.5
                      delay:1.0
                    options: UIViewAnimationOptionCurveEaseIn
                 animations:^
                     self.topView.frame = CGRectMake(16.0, 
    self.topView.frame.size.height/8.0, self.topView.frame.size.width, 
    self.topView.frame.size.height);
                     self.bottomView.frame = CGRectMake(16.0, (self.view.bounds.size.height-self.bottomView.frame.size.height)-20.0, self.bottomView.frame.size.width, self.bottomView.frame.size.height);
                 
                 completion:^(BOOL finished)
                     NSLog(@"Done!");
                 ];


- (IBAction)animateViewsOut:(id)sender 
    CGRect basketTopFrame = self.topView.frame;
    basketTopFrame.origin.y = -basketTopFrame.size.height;

    CGRect basketBottomFrame = self.bottomView.frame;
    basketBottomFrame.origin.y = self.view.bounds.size.height;


    [UIView animateWithDuration:0.5
                      delay:1.0
                    options: UIViewAnimationOptionCurveEaseOut
                 animations:^
                     [self.view layoutIfNeeded];

                     self.topView.frame = basketTopFrame;
                     self.bottomView.frame = basketBottomFrame;
                 
                 completion:^(BOOL finished)
                     NSLog(@"Done!");
                 ];

【问题讨论】:

使用约束时,您不应该调整框架。您应该修改约束的constant 属性(或停用一个约束并激活另一个)。 ***.com/a/28329399/1271826 的可能重复项(尽管如此,诚然 Swift 的回答;这个想法在 Objective-C 中是相同的)。或者这里是说明约束动画的 Objective-C 答案:***.com/a/14190042/1271826。 谢谢罗伯。我已经添加了通过 IBOutlet 连接的约束并使用常量为它们设置动画,但是如何在屏幕外启动 UIView? leftConstraint.constant - 320. 是如何在屏幕外启动的示例。 【参考方案1】:

使用约束时,您不应该调整框架。您应该修改约束的constant 属性(或停用一个约束并激活另一个)。

这是一个从顶部动画顶视图的示例,假设您将名为 topConstraint@IBOutlet 添加到视图 topView 的顶部约束:

在 Objective-C 中:

- (void)viewDidAppear:(BOOL)animated 
    [super viewDidAppear:animated];

    self.topConstraint.constant = -self.topView.frame.size.height;  // or whatever you want
    [self.view layoutIfNeeded];
    [UIView animateWithDuration:0.5 delay:1 options:0 animations:^
        self.topConstraint.constant = 0;
        [self.topView layoutIfNeeded];
     completion:nil];

在斯威夫特中:

override func viewDidAppear(_ animated: Bool) 
    topConstraint.constant = -topView.frame.height  // or whatever you want
    view.layoutIfNeeded()
    UIView.animate(withDuration: 0.5, delay: 1, animations: 
        topConstraint.constant = 0
        self.view.layoutIfNeeded()
    )

【讨论】:

以上是关于如何为具有约束的 UIView 设置动画?的主要内容,如果未能解决你的问题,请参考以下文章

如何为 UIView 关键帧动画设置动画曲线(`func UIView.animateKeyframes()`)

如何为 UIView 动画设置相同的速度

如何为嵌入在 UITableViewCell 中的 UIView 设置动画

iOS:如何为 3 个具有相同持续时间和重复的序列设置动画?

当UIVIew隐藏在sameView中时,如何为UIview设置动画

如果约束是使用 VFL 以编程方式创建的,如何为约束更改设置动画?