views:

853

answers:

4

I have set up an animation in Xcode using an NSTimer, and It kept repeating over and over, so i used this command:

else if(gordon.image == pigImage11)
    [animationTimer invalidate];

So, when gordon (a UIImageView) image is set to pigImage11, The timer invalidates, this gave the desired effect of stopping the animation constantly repeating, But stopped the timer being used again, so how would I make the timer usable again, But have it invalidate itself on that frame? For the sake of further clarification here's my entire code:

- (IBAction)startClick:(id)sender{
    animationTimer = [NSTimer scheduledTimerWithTimeInterval:(1.00/30.00) target:self selector:@selector(tick) userInfo:nil repeats:YES];
}
- (void)tick{
    [self animatePig];
}
- (void)animatePig{
    UIImage *pigImage1=[UIImage imageNamed:@"gordonapple0004.png"];
    UIImage *pigImage2=[UIImage imageNamed:@"gordonapple0005.png"];
    UIImage *pigImage3=[UIImage imageNamed:@"gordonapple0006.png"];
    UIImage *pigImage4=[UIImage imageNamed:@"gordonapple0007.png"];
    UIImage *pigImage5=[UIImage imageNamed:@"gordonapple0008.png"];
    UIImage *pigImage6=[UIImage imageNamed:@"gordonapple0009.png"];
    UIImage *pigImage7=[UIImage imageNamed:@"gordonapple0010.png"];
    UIImage *pigImage8=[UIImage imageNamed:@"gordonapple0011.png"];
    UIImage *pigImage9=[UIImage imageNamed:@"gordonapple0012.png"];
    UIImage *pigImage10=[UIImage imageNamed:@"gordonapple0013.png"];
    UIImage *pigImage11=[UIImage imageNamed:@"gordonapple0014.png"];
    UIImage *pigImage12=[UIImage imageNamed:@"gordonapple0015.png"];
    UIImage *pigImage13=[UIImage imageNamed:@"gordonapple0016.png"];


    if(gordon.image == pigImage1)
        gordon.image = pigImage2;
    else if(gordon.image == pigImage2)
        gordon.image = pigImage3;
    else if(gordon.image == pigImage3)
        gordon.image = pigImage4;
    else if(gordon.image == pigImage4)
        gordon.image = pigImage5;
    else if(gordon.image == pigImage5)
        gordon.image = pigImage6;
    else if(gordon.image == pigImage6)
        gordon.image = pigImage7;
    else if(gordon.image == pigImage7)
        gordon.image = pigImage8;
    else if(gordon.image == pigImage8)
        gordon.image = pigImage9;
    else if(gordon.image == pigImage9)
        gordon.image = pigImage10;
    else if(gordon.image == pigImage10)
        gordon.image = pigImage11;
    else if(gordon.image == pigImage11)
        [animationTimer invalidate];
    else
        gordon.image = pigImage1;
}

- (void)stopTimer
{
    [animationTimer invalidate];
    [animationTimer release];
}
A: 

How about not invalidating the timer and just setting a "don't animate" flag instead?

Rhythmic Fistman
Okay, could you give me an example of the code that I could use to do that? Sorry about the noobishness but I only started developing 3 weeks ago.
A: 
[[NSRunLoop currentRunLoop] addTimer:animationTimer
                             forMode:NSDefaultRunLoopMode];

But you must not release the timer after invalidating, of course.

Nikolai Ruhe
Okay, thanks for that, but I still can't seem to get the button that starts the timer to work after invalidating, where would you implement that code into my code?
A: 

Why not use UIImageView's built in animation:

UIImageView* gordonView = [[UIImage alloc]init];
gordonview.animationImages = [NSArray arrayWithObjects: pigImage1, pigimage2, etc., nil];
gordonView.animationDuration = 0.5f; // about 30fps with your 13 images. 
//Set gordon's frame here
[gordonView startAnimating];

Disclosure, I typed this into SO, not Xcode I'm certain it will not compile but at least you know what to look for in the SDK.

Roger Nolan
0.5 (seconds) = 2 fps. Wouldn't 30fps equal 1/30 = 0.03?
Brock Woolf
1/30 ≠ 0.03. If you want 1/30, just say that: `1.0 / 30.0`.
Peter Hosey
+1  A: 

You can reuse a timer like this:

- (void) startTimer {
    if ( myTimer == nil ) {
        myTimer = [NSTimer scheduledTimerWithTimeInterval: 5.0f
                   target: self
                   selector: @selector(myTimerAction:)
                   userInfo: nil
                   repeats: NO];
    }
}

- (void) stopTimer {
    if ( myTimer || [myTimer isValid])
    {
        [myTimer invalidate];
        myTimer = nil;
    }
}
Brock Woolf
This is the way I'm using NSTimers in one of my shipping apps. Works quite well.
Shawn Craver