是否可以在不使用完成块的情况下在 UIView 上执行多个动画 [英] Is it posible to do multiple animations on UIView without using completion block

查看:31
本文介绍了是否可以在不使用完成块的情况下在 UIView 上执行多个动画的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个简单的问题,只是为了说明问题,我的具体代码要复杂得多.

This is simple question just for illustrating point, my concrete code is much more complicated.

假设我的 UILabel 位于左上角.
使用此代码,我会将其移至右上角:

Let say that I have UILabel that is position on TOP LEFT.
With this code, I will move it to TOP RIGHT:

    // labelMove is moved to TOP RIGHT
    [UIView animateWithDuration:1.0f
                          delay:2.0f
                        options:UIViewAnimationOptionCurveEaseOut
                     animations:^
     {
         labelMove.center = CGPointMake(250.0f, 40.0f);
     }
                     completion:nil];

如果我有这个代码:

// labelMove is moved to TOP RIGHT
[UIView animateWithDuration:1.0f
                      delay:2.0f
                    options:UIViewAnimationOptionCurveEaseOut
                 animations:^
 {
     labelMove.center = CGPointMake(250.0f, 40.0f);
 }
                 completion:nil];

// labelMove is moved to BOTTOM RIGHT
[UIView animateWithDuration:1.0f
                      delay:2.0f
                    options:UIViewAnimationOptionCurveEaseOut
                 animations:^
 {
     labelMove.center = CGPointMake(250.0f, 450.0f);
 }
                 completion:nil];

它不会从左上角开始,而是从右上角开始,然后从右下角开始.
不知何故,第一个动画没有动画,只有最后一个动画.
我不明白为什么,但这并不重要.
我可以把第二个完成:先阻止然后它就会起作用.
喜欢这个代码.

It will not start from TOP LEFT, but from TOP RIGHT, and then go BOTTOM RIGHT.
Somehow first animation is not animated, only the last one.
I do not get it why, but that is not so important.
I can put second in completion: block in first and then it will work.
Like this code.

// labelMove is moved to TOP RIGHT
[UIView animateWithDuration:1.0f
                      delay:2.0f
                    options:UIViewAnimationOptionCurveEaseOut
                 animations:^
 {
     labelMove.center = CGPointMake(250.0f, 40.0f);
 }
                 completion:^(BOOL finished){
                     // labelMove is moved to BOTTOM RIGHT
                     [UIView animateWithDuration:1.0f
                                           delay:2.0f
                                         options:UIViewAnimationOptionCurveEaseOut
                                      animations:^
                      {
                          labelMove.center = CGPointMake(250.0f, 450.0f);
                      }
                                      completion:nil];
                 }];

问题
是否有可能从最后的代码生效但不以任何方式使用完成块.
这对我来说非常重要.
我尝试使用 CABasicAnimation,但无法做到,也许有更多经验的人可以?
我相信一定有办法,但我就是想不通.

QUESTION
Is it posible to have effect from last code but without using completion block in any way.
That is very important for me.
I try with CABasicAnimation, but could not do it, maybe somebody with more experience can ?
I am sure that there must be some way, but I just can not figure it out.

推荐答案

没有完成块的代码不起作用,因为您正试图在完全相同的时间点将标签动画化到两个不同的位置.这在物理上是不可能的.

Your code with no completion block does not work because you are attempting to animate the label to two different locations at exactly the same point in time. This is physically impossible.

当您在完成块内运行第二个动画时,您是在第一个动画之后运行它,而不是同时.为了达到同样的效果,调度第二个动画,让它在第一个动画之后执行.由于第一个动画需要 2.0 延迟 + 1.0 持续时间 = 3.0 秒才能完成,因此在 3.0 秒后调度.见下文.

When you run that second animation inside a completion block, you are running it after the first animation, instead of at the same time. To achieve the same effect, dispatch the second animation so that it is performed after the first animation. Since the first animation will take 2.0 delay + 1.0 duration = 3.0 seconds to complete, dispatch after 3.0 seconds. See below.

// labelMove is moved to TOP RIGHT
[UIView animateWithDuration:1.0f
                      delay:2.0f
                    options:UIViewAnimationOptionCurveEaseOut
                 animations:^
 {
     labelMove.center = CGPointMake(250.0f, 40.0f);
 }
                 completion:nil];

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    // labelMove is moved to BOTTOM RIGHT
    [UIView animateWithDuration:1.0f
                          delay:2.0f
                        options:UIViewAnimationOptionCurveEaseOut
                     animations:^
     {
         labelMove.center = CGPointMake(250.0f, 450.0f);
     }
                     completion:nil];
});

请注意,如果不使用完成块,则无法确保第一个动画真正完成动画.在实践中,这通常应该没问题.

Just be aware that without using the completion block, you cannot insure the first animation is truly finished animating. In practice this should usually be fine.

这篇关于是否可以在不使用完成块的情况下在 UIView 上执行多个动画的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆