How to know if several blocks have completed execu

2019-03-29 08:48发布

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

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

3条回答
Emotional °昔
2楼-- · 2019-03-29 09:39

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.

查看更多
Emotional °昔
3楼-- · 2019-03-29 09:45

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

 [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.

查看更多
▲ chillily
4楼-- · 2019-03-29 09:45

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.

查看更多
登录 后发表回答