I have what I thought was a very simple case of animation. There is a view that sits at 0 alpha unless it becomes 1 until a future animation with one type of event, or becomes 1 for a few seconds with another type of event. My problem is that when those two events are called consecutively, so, in effect the following code is run:
[UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionBeginFromCurrentState animations:^(void){
self->bkgView.alpha = 1.0;
} completion:^(BOOL finished){}];
[UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionBeginFromCurrentState animations:^(void){
self->bkgView.alpha = 1.0;
} completion:^(BOOL finished){
NSLog(@"completion finished: %d", finished);
if (finished)
[UIView animateWithDuration:0.5 delay:3 options:UIViewAnimationOptionBeginFromCurrentState animations:^(void){
self->bkgView.alpha = 0;
} completion:^(BOOL finished){}];
}];
I would think that the second call just cancels the first call and takes over from wherever that one was, so I get the flashing to alpha 1 for a few seconds. What actually happens is no animation at all, the completion block is called immediately with finished as true - so no indication it was cancelled. I thought I'd ask instead of banging my head on this seemingly trivial case, what am I doing wrong?
Edit: I meant it when I said that the code is trivial, but here is the entire viewcontroller you can put on a new single view project if you want to try it:
#import "ViewController.h"
@interface ViewController () {
UIView *bkgView;
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
CGFloat x = 20;;
for (NSString *str in @[@"show", @"flash", @"both"]) {
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button addTarget:self action:NSSelectorFromString(str) forControlEvents:UIControlEventTouchUpInside];
[button setTitle:str forState:UIControlStateNormal];
button.backgroundColor = [UIColor grayColor];
button.frame = CGRectMake(x, 100, 80, 40);
[self.view addSubview:button];
x += 100;
}
bkgView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 100)];
bkgView.backgroundColor = [UIColor blackColor];
bkgView.alpha = 0;
[self.view addSubview:bkgView];
}
-(void)both {
[self show];
[self flash];
}
-(void)show {
[UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionBeginFromCurrentState animations:^(void){
self->bkgView.alpha = 1.0;
} completion:^(BOOL finished){}];
}
-(void)flash {
[UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionBeginFromCurrentState animations:^(void){
self->bkgView.alpha = 1.0;
} completion:^(BOOL finished){
[UIView animateWithDuration:0.5 delay:3 options:UIViewAnimationOptionBeginFromCurrentState animations:^(void){
self->bkgView.alpha = 0;
} completion:^(BOOL finished){}];
}];
}
It loads three buttons. If you click "show", it fades in a rectangle. If you click "flash" it fades in a rectangle for 3 seconds then fades it out. My problem is if you click "both" which might not make much sense in this trivial example, but simulates calling the show and flash actions consecutively which can happen in my original code. I expected it to behave the same as "flash" (as it should just take over from the "show" function immediately), but it does nothing, the rectangle is not shown.