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...
精彩评论