Search code examples
iphoneobjective-cxcodecore-animationnstimer

Core Animation and NSTimer


What i'm trying to do is animating a label when timer ticks. I have a window based application.

  1. I tried core animation in a while loop, but program just freezes.
  2. I tried core animation triggered by a timer(NSTimer), but nothing happens.

Problem : I debugged program, everything looks fine, all the statements are being executed, but nothing happens. I thought that core animation in a loop or triggered by a timer is not allowed. Is there any other way ?

What i have is :

drawingTimer = [NSTimer scheduledTimeWithTimeInterval:60.0 target:self
                selector:@selector(slideWords) userInfo:nil repeats:NO];

-void (slideWords){
 randomNumber = 1 + arc4Random()%2;

 if(randomNumber = 1){
    Redlabel.alpha = 1.0;
    RedLabel.frame = CGRectMake(0, -50, 320, 100);
    [UIWindow animateWithDuration:5.0 animations:^{
        Redlabel.alpha = 1.0;
        Redlabel.frame = CGRectMake(0,300,320,100);
    }completion:^(BOOL finished){
        [UIWindow animateWithDuration:0.5 delay:0.5 options:0 animations:^{
            Redlabel.alpha = 0.0;
        }completion:^(BOOL finished){
        }];
    }];
 }

 if(randomNumber = 2){
    GreenLabel.alpha = 1.0;
    GreenLabel.frame = CGRectMake(0, -50, 320, 100);
    [UIWindow animateWithDuration:5.0 animations:^{
        GreenLabel.alpha = 1.0;
        GreenLabel.frame = CGRectMake(0,300,320,100);
    }completion:^(BOOL finished){
        [UIWindow animateWithDuration:0.5 delay:0.5 options:0 animations:^{
            GreenLabel.alpha = 0.0;
        }completion:^(BOOL finished){
        }];
    }];
 }

}


Solution

  • As danh says in his comment, both of your if statements should be

    if (randomNumber == value)
    

    A single equals is not a comparison operator, it's an assignment operator. The compiler should be giving you a warning about that.

    Second, animateWithDuration is a UIView method, not a UIWindow method. I guess the compiler allows what you wrote because UIWindow inherits from UIView, but sending a class message to a subclass that does not implement that method is a bad idea.

    Your animation methods should read

    [UIView animateWithDuration: x...
    

    Third, Core Animation triggered with a timer should work just fine. However, since your timer is not repeating, why use a timer at all? Use the form of the animation method that takes a delay, and make your code cleaner. Then you don't need a timer or a separate "slideWords" method at all. Your code could look like this:

     randomNumber = 1 + arc4Random()%2;
    
     if(randomNumber = 1){
        Redlabel.alpha = 1.0;
        RedLabel.frame = CGRectMake(0, -50, 320, 100);
        [UIWindow animateWithDuration:5.0 
          delay: 60.0
          options: 0
          animations:^{
            Redlabel.alpha = 1.0;
            Redlabel.frame = CGRectMake(0,300,320,100);
        }completion:^(BOOL finished){
            [UIWindow animateWithDuration:0.5 delay:0.5 options:0 animations:^{
                Redlabel.alpha = 0.0;
            }completion:^(BOOL finished){
            }];
        }];
     }
    
     if(randomNumber = 2){
        GreenLabel.alpha = 1.0;
        GreenLabel.frame = CGRectMake(0, -50, 320, 100);
        [UIWindow animateWithDuration:5.0 
          delay: 60.0
          options: 0
          animations:^{
            GreenLabel.alpha = 1.0;
            GreenLabel.frame = CGRectMake(0,300,320,100);
        }completion:^(BOOL finished){
            [UIWindow animateWithDuration:0.5 delay:0.5 options:0 animations:^{
                GreenLabel.alpha = 0.0;
            }completion:^(BOOL finished){
            }];
        }];
     }
    

    Fourth: There is a strong naming convention in Cocoa that you should follow. Method names and variable names should start with a lower case letter and each word within the name should be capitalized. Only class names should be capitalized. (Apple's Core Foundation functions follow different naming rules, but those aren't methods, they're C functions...)

    So your "RedLabel" should be "redLabel" and "GreenLabel" should be "greenLabel"