Access Method After UIImageView Animation Finish

后端 未结 7 888
清酒与你
清酒与你 2020-12-01 11:47

I have an array of images loaded into a UIImageView that I am animating through one cycle. After the images have been displayed, I would like a @selector to be

相关标签:
7条回答
  • 2020-12-01 11:49

    With this method you avoid timers to fire while the imageView is still animating due to slow image loading. You could use both performSelector: withObject: afterDelay: and GCD in this way:

    [self performSelector:@selector(didFinishAnimatingImageView:)
               withObject:imageView
               afterDelay:imageView.animationDuration];
    

    /!\ self.imageView.animationDuration has to bet configured before startAnimating, otherwise it will be 0

    Than if -(void)didFinishAnimatingImageView:create a background queue, perform a check on the isAnimating property, than execute the rest on the main queue

    - (void)didFinishAnimatingImageView:(UIImageView*)imageView
    {
    
       dispatch_queue_t backgroundQueue = dispatch_queue_create("com.yourcompany.yourapp.checkDidFinishAnimatingImageView", 0);
       dispatch_async(backgroundQueue, ^{
    
           while (self.imageView.isAnimating)
               NSLog(@"Is animating... Waiting...");
    
           dispatch_async(dispatch_get_main_queue(), ^{
    
              /* All the rest... */
    
           });
    
       });
    
    }
    
    0 讨论(0)
  • 2020-12-01 11:52

    in ImageView.m

    - (void) startAnimatingWithCompleted:(void (^)(void))completedHandler {
    if (!self.isAnimating) {
        [self startAnimating];
        dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, self.animationDuration * NSEC_PER_SEC);
        dispatch_after(popTime, dispatch_get_main_queue(),completedHandler);       
    }}
    
    0 讨论(0)
  • 2020-12-01 11:54

    There is no way to do this precisely with UIImageView. Using a delay will work most of the time, but there can be some lag after startAnimating is called before the animation happens on screen so its not precise. Rather than using UIImageView for this animation try using a CAKeyframeAnimation which will call a delegate method when the animation is finished. Something along these lines:

    NSArray * imageArray = [[NSArray alloc] initWithObjects:
                        (id)[UIImage imageNamed:@"HowTo1.png"].CGImage, 
                        (id)[UIImage imageNamed:@"HowTo2.png"].CGImage,
                        nil];
    UIImageView * instructions = [[UIImageView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    
    //create animation
    CAKeyframeAnimation *anim = [CAKeyframeAnimation animation];
    [anim setKeyPath:@"contents"];
    [anim setValues:imageArray];
    
    [anim setRepeatCount:1];
    [anim setDuration:1];
    anim.delegate = self; // delegate animationDidStop method will be called
    
    CALayer *myLayer = instructions.layer;
    
    [myLayer addAnimation:anim forKey:nil];
    

    Then just implement the animationDidStop delegate method

    0 讨论(0)
  • 2020-12-01 11:58

    You can create a timer to fire after the duration of your animation. The callback could process your logic you want to execute after the animation finishes. In your callback be sure check the status of the animation [UIImageView isAnimating] just in case you want more time to let the animation finish.

    0 讨论(0)
  • 2020-12-01 11:59

    You can simple use this category UIImageView-AnimationCompletionBlock

    And for Swift version: UIImageView-AnimationImagesCompletionBlock

    Take a look on ReadMe file in this class..

    Add UIImageView+AnimationCompletion.h and UIImageView+AnimationCompletion.m files in project and them import UIImageView+AnimationCompletion.h file where you want to use this..

    For eg.

    NSMutableArray *imagesArray = [[NSMutableArray alloc] init];
    for(int i = 10001 ; i<= 10010 ; i++)
        [imagesArray addObject:[UIImage imageNamed:[NSString stringWithFormat:@"%d.png",i]]];
    
    self.animatedImageView.animationImages = imagesArray;
    self.animatedImageView.animationDuration = 2.0f;
    self.animatedImageView.animationRepeatCount = 3;
    [self.animatedImageView startAnimatingWithCompletionBlock:^(BOOL success){
     NSLog(@"Animation Completed",);}];
    
    0 讨论(0)
  • 2020-12-01 12:09

    Use performSelector:withObject:afterDelay::

    [self performSelector:@selector(animationDidFinish:) withObject:nil
        afterDelay:instructions.animationDuration];
    

    or use dispatch_after:

    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, instructions.animationDuration * NSEC_PER_SEC);
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
        [self animationDidFinish];
    });
    
    0 讨论(0)
提交回复
热议问题