如何知道几个块在执行之前是否已经完成执行?

时间:2021-12-18 21:10:01

I'm using animateWithDuration:animations:completion: to move several elements of my User Interface (about 4 elements) before removeFromSuperview: is called.

我正在使用animateWithDuration:animation:completion:在removeFromSuperview:被调用之前,移动我的用户界面的几个元素(大约4个元素)。

My question is, how can I know that all those animations have completed before calling removeFromSuperview:?

我的问题是,在调用removeFromSuperview:之前,我怎么知道这些动画已经完成?

3 个解决方案

#1


9  

Ok, to answer my own question.

好,回答我自己的问题。

I ended up doing something like this:

最后我做了这样的事情:

    // Create dispatch queue & group
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_group_t group = dispatch_group_create();

    // Two group enters
    dispatch_group_enter(group);
    dispatch_group_enter(group);

    // (notice the group parameter in dispatch_group_leave)
    [UIView animateWithDuration:0.3 animations:^{
        self.pickerView.frame = CGRectMake( self.pickerView.frame.origin.x
                                           , self.view.bounds.size.height + self.pickerView.frame.size.height/2
                                           , self.pickerView.frame.size.width
                                           , self.pickerView.frame.size.height);
    } completion:^(BOOL finished){
        dispatch_group_leave(group);
    }]; 


    [UIView animateWithDuration:0.3 animations:^{
        self.navigationBar.frame = CGRectMake( self.navigationBar.frame.origin.x
                                              , -self.navigationBar.frame.size.height
                                              , self.navigationBar.frame.size.width
                                              , self.navigationBar.frame.size.height);
    } completion:^(BOOL finished){
        dispatch_group_leave(group);
    }];

    // Finishing callback
    dispatch_group_notify(group, queue, ^{
        [self.view removeFromSuperview];
    });

    // Release the group
    dispatch_release(group);

I hope this can serve as an example for someone else.

我希望这能成为别人的榜样。

#2


1  

You can also use CATransaction. It will catch any embedded animations:

您还可以使用CATransaction。它将捕捉任何嵌入动画:

 [CATransaction begin];
 [CATransaction setCompletionBlock:^{ // all animations finished here }];
 [UIView animateWithDuration...
 [UIView animateWithDuration...
 ...
 [CATransaction commit];

This would allow you to not have to keep track of the animations yourself.

这将使您不必自己跟踪动画。

#3


0  

Create a dispatch queue, suspend it by the number of animations you are doing. Add a block to the queue that does the remove from superview. In the completion block of each animation resume the suspended queue. When the last one completes, the queued block will run.

创建一个调度队列,根据正在执行的动画数量将其挂起。向执行从父视图中删除操作的队列添加一个块。在每个动画的完成块中恢复挂起的队列。当最后一个完成时,队列块将运行。

#1


9  

Ok, to answer my own question.

好,回答我自己的问题。

I ended up doing something like this:

最后我做了这样的事情:

    // Create dispatch queue & group
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_group_t group = dispatch_group_create();

    // Two group enters
    dispatch_group_enter(group);
    dispatch_group_enter(group);

    // (notice the group parameter in dispatch_group_leave)
    [UIView animateWithDuration:0.3 animations:^{
        self.pickerView.frame = CGRectMake( self.pickerView.frame.origin.x
                                           , self.view.bounds.size.height + self.pickerView.frame.size.height/2
                                           , self.pickerView.frame.size.width
                                           , self.pickerView.frame.size.height);
    } completion:^(BOOL finished){
        dispatch_group_leave(group);
    }]; 


    [UIView animateWithDuration:0.3 animations:^{
        self.navigationBar.frame = CGRectMake( self.navigationBar.frame.origin.x
                                              , -self.navigationBar.frame.size.height
                                              , self.navigationBar.frame.size.width
                                              , self.navigationBar.frame.size.height);
    } completion:^(BOOL finished){
        dispatch_group_leave(group);
    }];

    // Finishing callback
    dispatch_group_notify(group, queue, ^{
        [self.view removeFromSuperview];
    });

    // Release the group
    dispatch_release(group);

I hope this can serve as an example for someone else.

我希望这能成为别人的榜样。

#2


1  

You can also use CATransaction. It will catch any embedded animations:

您还可以使用CATransaction。它将捕捉任何嵌入动画:

 [CATransaction begin];
 [CATransaction setCompletionBlock:^{ // all animations finished here }];
 [UIView animateWithDuration...
 [UIView animateWithDuration...
 ...
 [CATransaction commit];

This would allow you to not have to keep track of the animations yourself.

这将使您不必自己跟踪动画。

#3


0  

Create a dispatch queue, suspend it by the number of animations you are doing. Add a block to the queue that does the remove from superview. In the completion block of each animation resume the suspended queue. When the last one completes, the queued block will run.

创建一个调度队列,根据正在执行的动画数量将其挂起。向执行从父视图中删除操作的队列添加一个块。在每个动画的完成块中恢复挂起的队列。当最后一个完成时,队列块将运行。