Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Repeat an animation a variable number of times

I was wondering how I can set an animation to repeat. The number of repetitions needs to be determined by a variable. In the following code, the variable int newPage should determine how often the animation is repeated.

I tried this, but the animation (which employs a block animation) was only executed once:

for (int temp = 1; temp <= newPage; temp++) {
            [self animatePage];
}

If I code the following, it works like I want it to, but this is hardcoded (i.e. the animation will be repeated twice) and I can't see a way of how to change the number of how often this animation is executed in code and according to my variable newPage:

[UIView animateWithDuration:0
                      delay:0.1
            options:UIViewAnimationOptionCurveEaseIn
             animations:^{[self animatePage];}
             completion:^(BOOL finished){[self animatePage];}];

I'd be very grateful for suggestions of how to repeat the same animation without having to hardcode the number of times I want this animation to be repeated.


EDIT:

I tried to implement the following code, but only one animation will actually be carried out:

        [UIView animateWithDuration:0
                          delay:1
                        options:UIViewAnimationOptionCurveEaseIn
                     animations:^{

                         [UIView setAnimationRepeatCount:2];
                         [self animatePage];

                     }
                     completion:nil];
like image 793
n.evermind Avatar asked Apr 28 '11 18:04

n.evermind


People also ask

Which option is used to repeat the animation?

Answer: Explanation:F5 key is used to repeat the animation.


4 Answers

Had the same problem - you were missing an an'UIViewAnimationOptionRepeat'

This should work:

 [UIView animateWithDuration:0
                      delay:1
                    options:UIViewAnimationOptionCurveEaseIn | UIViewAnimationOptionRepeat
                 animations:^{
                     [UIView setAnimationRepeatCount:2]; // **This should appear in the beginning of the block**
                     [self animatePage];

                 }
                 completion:nil];

Did the trick for me.

like image 139
YaDa Avatar answered Oct 14 '22 02:10

YaDa


Did you try to set the repeatCount? + (void)setAnimationRepeatCount:(float)repeatCount

I've tried the following code block, and it definitely repeats 2x for me (l was a UITextView that was scaled up by 2x in X dir and 3X in Y dir):

[UIView animateWithDuration:2 
delay:0.1 
options:UIViewAnimationOptionCurveEaseIn 
animations:^{ [UIView setAnimationRepeatCount:2]; 
l.transform = CGAffineTransformMakeScale(2,3); } completion:nil];
like image 21
DavidN Avatar answered Oct 14 '22 04:10

DavidN


the reason you arent seeing but one animation is that due to the fact that you are calling the animation from a loop in the same runloop, resuting in the last call winning (one animation)

instead of calling [self animatePage], try calling

[self performSelector:@selector(animatePage) withObject:nil afterDelay:.1 *temp];

this will create your calls on separate threads.

you may need to play with the delay interval

like image 20
Jason Cragun Avatar answered Oct 14 '22 04:10

Jason Cragun


To avoid the hiccup between animations, use keyframes. I wrote an extension that works on anything conforming to UIView (which is a ton of visual elements)

Swift 4:

import UIKit
extension UIView{
    func rotate(count: Float, _ complete: @escaping ()->()) {
        UIView.animateKeyframes(withDuration: 1.0, delay: 0, options: [.repeat], animations: {
            //to rotate infinitely, comment the next line
            UIView.setAnimationRepeatCount(count)
            //rotate the object to 180 degrees
            UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 0.5/1.0, animations: {
                self.transform = CGAffineTransform(rotationAngle: (CGFloat(Double.pi)))
            })
            UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 0.5/1.0, animations: {
                //rotate the object from 180 to 360 degrees
                self.transform = CGAffineTransform(rotationAngle: (CGFloat(Double.pi * 2)))
            })
        }, completion:{ _ in
            complete()
        })
    }
}

To call it anywhere in the app:

view.rotate() { /*do after*/ }
like image 45
froggomad Avatar answered Oct 14 '22 04:10

froggomad