9

I'm using CABasicAnimation for rotating UIImageView and I'm unable to resume paused animation. The animation starts in viewDidLoad method:

UIImageView *img = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"MyImage.png"]];
self.myImage = img;
[self.view addSubview:img];
[img release];
CABasicAnimation *fullRotation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
fullRotation.fromValue = [NSNumber numberWithFloat:0];
fullRotation.toValue = [NSNumber numberWithFloat:((360*M_PI)/180)];
fullRotation.duration = 10;
fullRotation.repeatCount = LARGE_VAL;
[img.layer addAnimation:fullRotation forKey:@"360"];

I need to have non-stop repeatable animation that resumes when the view appears on screen. So I have read this post (here) and implemented solution provided my apple (solution) for stopping and resuming layer animation. So, I have used these methods:

-(void)pauseLayer:(CALayer*)layer{
    CFTimeInterval pausedTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil];
    layer.speed = 0.0;
    layer.timeOffset = pausedTime;
}

-(void)resumeLayer:(CALayer*)layer{
    CFTimeInterval pausedTime = [layer timeOffset];
    layer.speed = 1.0;
    layer.timeOffset = 0.0;
    layer.beginTime = 0.0;
    CFTimeInterval timeSincePause = [layer convertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime;
    layer.beginTime = timeSincePause;
}

And I have added these methods to viewWillAppear and viewWillDisappear using and passing the layer of myImage property:

-(void)viewWillDisappear:(BOOL)animated{
    [self pauseLayer:self.myImage.layer];
}

- (void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    [self resumeLayer:self.myImage.layer];
}

The image does initial rotation when the view goes on screen. But then I'm putting some UIViewController on screen, then going back to the view with image rotation. The problem is the rotation of the image is not resumed when the view appears on screen. I have checked: my image UIImageView property is not nil, both viewWillDisappear and viewWillAppear methods get invoked. But the animation is not resuming. Did I something wrong, or missed something?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Centurion
  • 14,106
  • 31
  • 105
  • 197

3 Answers3

37

I had the same problem to yours. After a lot of googling... I got a solution for it.

In your case, just add the following code when you set CABasicAnimation:

fullRotation.removedOnCompletion = NO;

That's it. I hope it would work for you.

Younghan
  • 4,827
  • 3
  • 17
  • 9
6

Workarounds, workarounds and workarounds. So far, the solution I have got working is to throw away the suggested solution for stoping/resuming layer animation :), to remove all the animations in viewWillDisappear:

[self.myImage.layer removeAllAnimations];  

and then to start a new animation in viewWillAppear. I know that I'm not resuming the old one but, in my case, it's not so visible to the humans eye, so I think I will be good.

Dharman
  • 30,962
  • 25
  • 85
  • 135
Centurion
  • 14,106
  • 31
  • 105
  • 197
0

I think your problem is memory management.

Try this instead:

UIImageView *img = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"MyImage.png"]];
self.myImage = img;
[img release];

CABasicAnimation *fullRotation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
fullRotation.fromValue = [NSNumber numberWithFloat:0];
fullRotation.toValue = [NSNumber numberWithFloat:((360*M_PI)/180)];
fullRotation.duration = 10;
fullRotation.repeatCount = LARGE_VAL;
[self.myImage.layer addAnimation:fullRotation forKey:@"360"];

[self.view addSubview:self.myImage];

Tell me if this works.

MiguelB
  • 1,913
  • 18
  • 20
  • I have checked the physical address of my image view object property (both view and its layer) and the addresses are the same when entering viewWillAppear and viewWillDisappear. Image object is not release, because I have checked that it's not nil – Centurion Aug 05 '11 at 10:39
  • myImage property has nonatomic and retain attributes. Therefore the image object is retained after the initial self.myImage = img assignment. – Centurion Aug 05 '11 at 10:42
  • Moving [self.view addSubview:self.myImage] to the bottom does not solve the problem, animation still does not resume after coming back. – Centurion Aug 05 '11 at 10:45
  • @Centurion Moving the addsubview: line to the bottom is just a personal preference... don't focus on that. I changed other more important things. For instance, you were setting the value of self.myImage to img, and later adding the animation to img but you never set the property again... and later when you call pause or resume you do it through self.myImage (which is not animating since you didn't add the animation before to the property! The value it retained was of img before you added the animation). – MiguelB Aug 05 '11 at 11:17
  • Sorry, my mistake by adding animation to released img. But I' have fixed it to [self.sunRaysBgImg.layer addAnimation:fullRotation forKey:@"360"]; but still animation is not resuming after putting and removing another UIViewController :( Do you have this solution working? – Centurion Aug 05 '11 at 11:32