I want to flash an UIImageview on the iPad, how do

2019-03-19 17:13发布

问题:

I want to let a UIImageView flash several times.

Currently I don't know how to do that.

Actual code:

-(void)arrowsAnimate{
    [UIView animateWithDuration:1.0 animations:^{
        arrow1.alpha = 1.0;
        arrow2.alpha = 1.0;
        arrow3.alpha = 1.0;
        NSLog(@"alpha 1");
    } completion:^(BOOL finished){        

        [self arrowsAnimate2];

    }];
}

-(void)arrowsAnimate2{
    [UIView animateWithDuration:1.0 animations:^{
         arrow1.alpha = 0.0;
         arrow2.alpha = 0.0;
         arrow3.alpha = 0.0;
         NSLog(@"alpha 0");
    } completion:^(BOOL finished){;}];
}

later on I call it like this:

for (int i = 0;i < 10; i++){
[self arrowsAnimate]; }

This gives me 10x alpha 1, and then 10x alpha 0. In the middle we see only one animation. Any suggestions?

Thanks.

回答1:

There is a simpler way to achieve a flashing animation using only 1 animation block:

aview.alpha = 1.0f;
[UIView animateWithDuration:0.5f
                      delay:0.0f 
                    options:UIViewAnimationOptionAutoreverse
                 animations:^ {
       [UIView setAnimationRepeatCount:10.0f/2.0f];
       aview.alpha = 0.0f;
} completion:^(BOOL finished) { 
       [aview removeFromSuperview]; 
}];    

The trick is to use [UIView setAnimationRepeatCount:NTIMES/2]; *_inside_* your animation block. No need for extra functions or extra loops.



回答2:

Use

+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion

and pass the UIViewAnimationOptionRepeat and probably UIViewAnimationOptionAutoreverse in your options. You shouldn't need to provide a completion block and only perform the first animation.

Edit: here is some sample code for an image that fades in and out indefinitely.

[UIView animateWithDuration:1.0 
                      delay:0.0 
                    options:(UIViewAnimationOptionRepeat | UIViewAnimationOptionAutoreverse) 
                 animations:^{
                     self.myImageView.alpha = 1.0;
                 }
                 completion:NULL];

Edit 2: I see you actually need to flash it 10 times only. I wasn't able to do that with blocks actually. When the completion block executed, the animation seemed to complete instantly the remaining 9 times. I was however able to do this with just the old-style animations quite easily.

[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.0];
[UIView setAnimationRepeatCount:10.0];
[UIView setAnimationRepeatAutoreverses:YES];

self.myImageView.alpha = 1.0;

[UIView commitAnimations];

Edit 3: I found a way to do this with blocks.

- (void)animate
{
    if (self.animationCount < 10)
    {
        [UIView animateWithDuration:1.0 
                         animations:^{
                             self.myImageView.alpha = 1.0;
                         }
                         completion:^(BOOL finished){
                             [self animateBack];
                         }];
    }
}

- (void)animateBack
{
    [UIView animateWithDuration:1.0 
                     animations:^{
                         self.myImageView.alpha = 0.0;
                     }
                     completion:^(BOOL finished){
                         self.animationCount++;
                         [self animate];
                     }];
}


回答3:

Above blinking may not work when your app go background and foreground at time of blinking. Instead of these you can take a transparent image and your actual image and animate your ImageView

UIImageView *imageview=[UIImageView new];
imageview.animationDuration=1;
imageview.animationImages = your array of images;
[imageview startAnimating];


回答4:

You need to wait for an animation to complete before launching a new one. You could chain your completion block in animate2 to go back to animate, and stop based on a counter property, implementing your loop in the animate/completion blocks instead of a separate loop.