简体   繁体   English

连续的iOS动画*没有*块?

[英]Sequential iOS animation *without* blocks?

How might one animate a UIView without using block structure? 使用块结构的情况下如何为UIView设置动画? I just need to force an animation to execute immediately after it is called, and I don't have the luxury of putting the rest of my program in a completion block based on the code structure. 我只需要强制动画在调用后立即执行,就没有足够的精力将我的程序的其余部分放在基于代码结构的完成块中。

To be specific, right now, here is what is happening 具体来说,现在正在发生什么

while (actionsRemaining)
{
   [self performDesiredAnimation];
   ....computation ....
   [barWidget decreaseValueTo:resultOfComputation];
}

When I run this code, all [performDesiredAnimation] animations happen simultaneously with the 10 or so barWidgets all decreasing simultaneously. 当我运行此代码时,所有[performDesiredAnimation]动画会同时发生,而10个左右的barWidgets会同时减少。 What I want is: 我想要的是:

performDesiredAnimation1 --> barWidget decreases --> performedDesiredAnimation2 --> barWidget decreases --> performDesiredAnimation3 --> barWidget decreases --> ... however many unknown times. performDesiredAnimation1-> barWidget减少-> performDesiredAnimation2-> barWidget减少-> performDesiredAnimation3-> barWidget减少-> ...但是很多未知的时间。

I don't know how many times because actions will get removed from actionsRemaining if the barWidget decreases past a certain value, ie the number of loops will depend on intermediate calculations. 我不知道有多少次,因为动作将从动作中删除。如果barWidget减少到某个值以上,则剩余,即循环数将取决于中间计算。

To put it even more simply, what I want is the same result as I am seeing now when I call just one iteration of the loop 简而言之,我想要的结果与我现在只调用循环的一次迭代时看到的结果相同

[self performDesiredAnimation];
....computation ....
[barWidget decreaseValueTo:resultOfComputation];

, followed by the second iteration, followed by the third, all in isolation. ,然后进行第二次迭代,再进行第三次迭代,所有过程都是孤立的。 Right now the animation looks fine if I comment out the loop, but they all smash together when I keep the loop there. 现在,如果我注释掉循环,动画看起来就不错了,但是当我将循环保留在那里时,它们都粉碎了。 I just want the animations to execute sequentially from iteration to iteration, not all at once. 我只希望动画在迭代之间顺序执行,而不是一次全部执行。

Blocks are not what is causing you the problem. 障碍不是导致您出现问题的原因。 Your problem, I think, is your "animations in a for loop" structure. 我认为您的问题是您的“ for循环动画”结构。

You need to keep your animating actions in a stack, and when one is finished, pop the next one off the stack and perform that. 您需要将动画动作保存在堆栈中,当一个动作完成时,将下一个动作弹出堆栈并执行。 Alternatively, check in the completion block for the animation if you need to continue, and if so, call the animating method again. 或者,如果需要继续,请在动画的完成块中签入,如果需要,请再次调用动画方法。 Something like: 就像是:

-(void)performAnimation
{
    [UIView animateWithDuration:0.25 
                     animations:^{[self performDesiredAnimations];}
                     completion:^(BOOL finished){
                                // It's not clear what your computations are or if they take any significant time
                                CGFloat result = [self doComputations];
                                [barWidget decreaseValueTo:resultOfComputation]
                                if (needToPerformAnotherSet) // Work this out however you need to
                                {
                                    [self performAnimation];
                                }
                            };
}

You can do this: 你可以这样做:

// Start the work in a background thread.

dispatch_async(dispatch_get_global_queue(0, 0), ^{

    while (actionsRemaining) {

        // Do your calculation in the background if your code will allow you to

        [self performDesiredAnimation];
        ....computation ....

        // Back to the main thread for a chunk of code

        dispatch_sync(dispatch_get_main_queue(), ^{

            // Or do it here if not

            [self performDesiredAnimation];
            ....computation ....

            // Finally, update your widget.

            [barWidget decreaseValueTo:resultOfComputation];
        }
    }
} 

} }

Since your loop enters the async'ed background loop on each iteration the application's main run loop will get a chance to update your UI with the value that you set in the sync'd block. 由于您的循环会在每次迭代中进入异步后台循环,因此应用程序的主运行循环将有机会使用您在sync'd块中设置的值来更新您的UI。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM