如何使用GCD来控制动画序列 [英] How to use GCD to control animation sequence

查看:158
本文介绍了如何使用GCD来控制动画序列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个查看来显示和隐藏提供给用户一些提示。

I have a View to show and hide to give users some hint.

显示和隐藏方法看起来有些像这样的:

The show and hide method look some like this:

-(void)show{
    [UIView animateWithDuration:3.0f
                 animations:^{
                     //do something to show self to give hint;
                     self.frame = CGRectMake(0,0,0,0);
                 } completion:nil];
}

-(void)hide{
    [UIView animateWithDuration:3.0f
                 animations:^{
                     //do something to hide self to give hint;
                     self.frame = CGRectMake(centerX,centerY,100,100);
                 } completion:nil];
}

呈现出新的观点时,我必须调用隐藏方法,然后 show方法。但工期延误,3.0F,会造成一定的误差。我用这样的方法:

when showing a new view, I must call hide method, and then show method. But the duration delay, 3.0f, will cause some error. I was using methods like this:

dispatch_async(dispatch_get_main_queue(), ^{
    [view hide];
});

dispatch_async(dispatch_get_main_queue(), ^{
    [view show];
});

我打电话 show方法之后隐藏方法。动画不能执行,因为它们被提交给队列的顺序。我要的是 show方法隐藏方法完成后,正是执行。如何控制这两个方法的顺序。

I was calling show method right after hide method. Animations cannot execute as the sequence they are submitted to the queue. What I want is the show method executed exactly after the hide method completed. How can I control the order of these two methods.

我想我不能使用完成处理程序,因为我不能保证,其中这两种方法的调用,或视图是否显示,当我打电话给另一个 show方法隐藏方法

I think I cannot use the completion handler cause I cannot assure where these two methods are called, or whether the view is shown when I called another show method or hide method.

如果我不明白,有什么建​​议?我会重新编辑我的问题。

If I am not clear, any suggestions? I will reedit my questions.

PS:

PS:

这不只是一个闪光灯。当一个 show方法被调用时,我不能保证最后一个视图显示或隐藏,最后视图正在显示多长时间,也就是说,如果正在显示的视图和隐藏方法被调用,并已经完成,那么<​​code>显示方法被调用时,结果是正确的。如果正在显示的视图,另一条线索视图需要是presented,我会打电话给隐藏,然后再显示,因为 main_queue 是串行的,但syncly执行的动画块,所以结果是错误的。我找的是有没有GCD一些类型的锁,可以帮助我执行块之后最后的排队块完成,而不是在显示改变隐藏方法。原因有很多其他调用显示隐藏方法有许多种不同的参数,我需要解决许多地方在我的code。

It's not just a flash. When next show method is called, I can not assure the last view is shown or hide and how long the last view is being shown, that is, if the view is being shown and the hide method has been called and already completed, then the show method is called, the result is right. If the view is being shown, another hint view need to be presented, I will call hide first, then show, since the main_queue is serial but the animation block is executed syncly, so the result is wrong. I am looking for is there some kind of lock in GCD that can help me execute a block after last queued block is completed rather than changing within show and hide method. cause there are many other calls to show and hide method with many different kinds of parameters, I need to fix many places in my code.

推荐答案

如果你想在它们添加到队列的顺序一次执行一个任务,使用串行队列。

If you want to execute one task at a time in the order in which they are added to the queue, Use serial queue.

所以,你可以使用一个串行队列在同一时间的增加,以执行显示和隐藏任务。是的,主队列是确定的。

So you can use a serial queue to execute show and hide task at a time in the added order. Yeah, the main queue is ok for that.

不过的UIView -animateWithDuration:动画:方法是一种异步调用,该方法将立即返回。所以,你需要等待,直到完成块被调用。

However UIView -animateWithDuration:animations: method is kind of asynchronous call, the method returns immediately. So you need to wait until the completion block was called.

如果你想等到有些任务是完成了,使用派遣组。但是你应该避免等待像在主队列中。它会阻止主队列。糟糕的应用程序。

If you want to wait until some tasks were finished, Use dispatch group. But you should avoid to wait like that on the main queue. It blocks the main queue. Bad app.

因此​​,您可能需要使用串行队列调度组,如下。

Thus, you might need to use a serial queue and dispatch group as the following.

属性和初始化

@property (nonatomic, strong) dispatch_queue_t serialQueue;
@property (nonatomic, strong) dispatch_group_t group;

-(void)initQueue {
    // create a serial queue
    self.serialQueue = dispatch_queue_create("com.example.serialQueue", 0);
    // create a dispatch group
    self.group = dispatch_group_create();
}

这使用串行队列和方法的调度组

a method that uses the serial queue and the dispatch group

-(void)animateSyncWithDuration:(NSTimeInterval)duration animations:(block_t)animations {
    dispatch_async(self.serialQueue, ^{
        /*
         * This block is invoked on the serial queue
         * This block would never be executed concurrently
         */

        /*
         * Enter the dispatch group
         */
        dispatch_group_enter(self.group);

        dispatch_async(dispatch_get_main_queue(), ^{
            /*
             * This block is invoked on the main queue
             * It is safe to use UIKit
             */
            [UIView animateWithDuration:duration animations:animations completion:^{
                /*
                 * This completion block is invoked on the main queue
                 * Now leave the dispatch group
                 */
                dispatch_group_leave(self.group);
            }];
        });

        /*
         * Wait until leaving the dispatch group from the UIView animation completion block
         * It means it blocks the serial queue
         */
        dispatch_group_wait(self.group, DISPATCH_TIME_FOREVER);
    });
}

显示和隐藏

-(void)show{
    [self animateSyncWithDuration:3.0f animations:^{
        //do something to show self to give hint;
        self.frame = CGRectMake(0,0,0,0);
    }];
}

-(void)hide{
    [self animateSyncWithDuration:3.0f animations:^{
        //do something to hide self to give hint;
        self.frame = CGRectMake(centerX,centerY,100,100);
    }];
}

这篇关于如何使用GCD来控制动画序列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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