Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cancel block in UIView animateWithDuration

- (void) startLoading {

    [self blink];
} 

 - (void) blink {  

        [UIView animateWithDuration:0.5
                              delay: 0.0
                            options: UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionCurveEaseOut
                         animations:^{
                            //animate stuff
                         }
                         completion:^(BOOL finished){
                                 [self blink];    
                         }];

}

- (void) stopLoading {
    //What goes here?
}

In my UIView's initWithFrame, I build some loader graphics then start the loader animation from [self startLoading].

The question is now, how do I stop this 'infinite loop'? or what goes in the stopLoading or dealloc method to nicely tear everything down?

When I ignore the fact that a completion block is there and just release my UIView from the super view, everything goes fine for some seconds (more than the 0.5 sec specified) then the app crashes with a message:

malloc: * mmap(size=2097152) failed (error code=12) error: can't allocate region ** set a breakpoint in malloc_error_break to debug

I have a breakpoint in malloc_error_break and the culprit is the animation block.

I assume that the UIView was released by being removed from the super view and later on the completion block is executed, having a reference to self this is messaging a released object.

I can't find anything in the docs about canceling a 'queued' block.

like image 984
RickiG Avatar asked Feb 23 '23 12:02

RickiG


2 Answers

To cancel, do what you would do with any looping operation you want to be able to cancel: set a flag which you check each time before looping. So:

- (void) stopLoading {
    kCancel = YES;
}

And now your completion block looks like this:

completion:^(BOOL finished){
    if (!kCancel)
        [self blink];    
}];

kCancel could be an ivar, a static global variable, whatever.

like image 126
matt Avatar answered Mar 15 '23 05:03

matt


UIViewAnimationOptionRepeat has magic for u

[UIView animateWithDuration:0.5
                      delay: 0.0
                    options: UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionCurveEaseOut | UIViewAnimationOptionRepeat
                 animations:^{
                         //animate stuff
                 }
                 completion:^(BOOL finished){
                     NSLog(@"solved ");    
                 }];
like image 21
Vijay-Apple-Dev.blogspot.com Avatar answered Mar 15 '23 04:03

Vijay-Apple-Dev.blogspot.com