Question

I am trying to chain a set of UIView animateWithDuration: using the flag UIViewAnimationOptionRepeat The animation steps I am trying to repeat are:

  1. Animate a UIView 100 pixels to the left
  2. Fade the UIView out (opacity '0')
  3. While faded out (invisible), move it back to the original position (100 px to the right)
  4. Fade the UIView back in (set opacity to '1')
  5. Repeat the animation using flag UIViewAnimationOptionRepeat

I am not able to repeat the whole chain of animations - and only able to repeat the top most animation.

The code I have tried is this:

[UIView animateWithDuration:1 delay:0 options:UIViewAnimationOptionRepeat animations:^{
        self.handImageView.frame = CGRectMoveByXPixels(self.handImageView.frame, -100);
        [UIView animateWithDuration:0.5 delay:1 options:0 animations:^{
            self.handImageView.alpha = 0;
        } completion:^(BOOL finished) {
            self.handImageView.frame = CGRectMoveByXPixels(self.handImageView.frame, 100);
            [UIView animateWithDuration:0.5 delay:0 options:0 animations:^{
                self.handImageView.alpha = 1;
            } completion:^(BOOL finished) {

            }];
        }];
    } completion:^(BOOL finished) {

    }];
Was it helpful?

Solution

The problem is that an animation that uses UIViewAnimationOptionRepeat never finishes and therefore never calls the completion block. However, you can repeat the animations using the performSelector method, as shown in the code below.

- (void)repeatingAnimationForView:(UIView *)view
{
    [UIView animateWithDuration:1 delay:0 options:0
    animations:^{ view.frame = CGRectMoveByXPixels(view.frame, -100); }
    completion:^(BOOL finished) {  if ( finished )  {

    [UIView animateWithDuration:0.5 delay:0 options:0
    animations:^{ view.alpha = 0; }
    completion:^(BOOL finished) {  if ( finished )  {

    view.frame = CGRectMoveByXPixels(view.frame, 100);

    [UIView animateWithDuration:0.5 delay:0 options:0
    animations:^{ view.alpha = 1; }
    completion:^(BOOL finished) {  if ( finished )  {

    if ( self.enableRepeatingAnimation )
        [self performSelector:@selector(repeatingAnimationForView:) withObject:view afterDelay:0];

    }}]; }}]; }}];
}

- (void)stopRepeatingAnimationForView:(UIView *)view
{
    self.enableRepeatingAnimation = NO;
    [view.layer removeAllAnimations];
    view.frame = CGRectMake( 100, 137, 80, 50 );
    view.alpha = 1;
}

- (void)startRepeatingAnimationForView:(UIView *)view
{
    self.enableRepeatingAnimation = YES;
    [self repeatingAnimationForView:view];
}

To stop the animations immediately, call the stopRepeatingAnimationForView method as shown above. To stop the animations at the end of a cycle, simply set self.enableRepeatingAnimation to NO.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top