开发者

NSTimer issue in Objective-C

开发者 https://www.devze.com 2023-04-06 05:31 出处:网络
I am working on a Kid\'s Book App for iPad. It has a UIView which loads UIImageView to display UIImages (JPEG\'s), user can swipe on images to browse through pages. I have also added some interactivit

I am working on a Kid's Book App for iPad. It has a UIView which loads UIImageView to display UIImages (JPEG's), user can swipe on images to browse through pages. I have also added some interactivity to some of the pages by adding another UIImageView which would load a PNG file and on Tap Gesture I animate them. One one of the pages I have an animation of leaf's falling on the screen (page 10) and I am using NSTimer for this, it works fine, however when I swipe and move to next page, the animation is still happening. I want the animation to run ONLY on page 10 and should stop immediately if I move to page 9 (backward swipe) or page 11 (forward swipe). I tried to put a condition (if (pageNum == 10)) and it stops after few seconds, so I can still see few leafs falling on previous/forward pages. I guess I understand why its happening but don't know how to fix it. Below is the code snippet:

- (void)handleTap:(UITapGestureRecognizer *)recognizer {
    NSLog(@"ChildrenBookViewController ==> handleTap.");
    switch (((UIGestureRecognizer *)recognizer).view.tag)      
    {
        case 1:
            //Some animation for Page 1
            break;
        case 2:
            //Some animation for Page 2
            break;
        //....
        case 10:
            // load our leaf image we will use the same image over and over
            leafImage = [UIImage imageNamed:@"leaf_small.png"];
            // start a timet that will fire 20 times per second
            timer = [NSTimer scheduledTimerWithTimeInterval:(0.05) target:self selector:@selector(onTimer) userInfo:nil repeats:YES];
            break;
        case 11:
            //Some animation for Page 11
            break;
        default:
            NSLog(@"ChildrenBookViewController ==> handleTap. Switch Case: DEFAULT");
            break;
    }
}

// Timer event is called whenever the timer fires
- (void)onTimer
{
    if (pageNum == 10)
    {
        // build a view from our leaf image
        UIImageView* leafView = [[UIImageView alloc] initWithImage:leafImage];

        // use the random() function to randomize up our leaf attributes
        int startX = round(random() % 1024);
        int endX = round(random() % 1024);
        double scale = 1 / round(random() % 100) + 1.0;
        double speed = 1 / round(random() % 100) + 1.0;

        // set the leaf start position
        leafView.frame = CGRectMake(startX, -100.0, 25.0 * scale, 25.0 * scale);
        //leafView.alpha = 0.25;

        // put the leaf in our main view
        [self.view addSubview:leafView];

        [UIView beginAnimations:nil context:leafView];
        // set up how fast the leaf will fall
        [UIView setAnimationDuration:5 * speed];

        // set the postion where leaf will move to
        leafView.frame = CGRectMake(endX, 500.0, 25.0 * scale, 25.0 * scale);

        // set a stop callback so we can cleanup the leaf when it reaches the
        // end of its animation
        [UIView setAnimationDidStopSelector:@selector(onAnimationComplete:finished:context:)];
        [UIView setAnimationDelegate:self];
        [UIView commitAnimations];
    }else{
        if (timer) {
            [timer invalidate];
            timer = nil;
        }
    }
}
- (void)onAnimationComplete:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context {
    UIImageView *leafView = context;
    [leafView removeFromSuperview];
    [leafView release]; 
开发者_运维技巧}


Instead of invalidating your timer in onTimer method, you should invalidate it in the callback you set for the swipe gesture (changing pages) page 9 and 11 cases. That way the timer will be invalidated as soon as the user swipes to switch pages.

EDIT: As @Alex noticed, this will only stop requesting more animations, but the already running will continue... I assume you have a reference to leafView so, you should call

[leafView.layer removeAllAnimations] and then remove it from superview or hide it or whatever you want...

0

精彩评论

暂无评论...
验证码 换一张
取 消