Search code examples
iosobjective-cuiviewcore-animationcalayer

UIView.layer.presentationLayer returns final value (rather than current value)


Here's some relevant code inside a UIView subclass:

- (void) doMyCoolAnimation {
  CABasicAnimation* anim = [CABasicAnimation animationWithKeyPath:@"position.x"];
  anim.duration = 4;
  [self.layer setValue:@200 forKeyPath:anim.keyPath];
  [self.layer addAnimation:anim forKey:nil];
}

- (CGFloat) currentX {
  CALayer* presLayer = self.layer.presentationLayer;
  return presLayer.position.x;
}

When I use [self currentX] while the animation is running, I get 200 (the end value) rather than a value between 0 (the start value) and 200. And yes, the animation is visible to the user, so I'm really confused here.

Here's the code where I call doMyCoolAnimation:, as well as currentX after 1 second.

[self doMyCoolAnimation];

CGFloat delay = 1; // 1 second delay
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
  NSLog(@"%f", [self currentX]);
});

Any ideas?


Solution

  • My UIView's layer's presentationLayer was not giving me the current values. It was instead giving me the end values of my animation.

     

    To fix this, all I had to do was add...

    anim.fromValue = [self.layer valueForKeyPath:@"position.x"];
    

    ...to my doMyCoolAnimation method BEFORE I set the end value with:

    [self.layer setValue:@200 forKeyPath:@"position.x"];
    

     

    So in the end, doMyCoolAnimation looks like this:

    - (void) doMyCoolAnimation {
      CABasicAnimation* anim = [CABasicAnimation animationWithKeyPath:@"position.x"];
      anim.duration = 4;
      anim.fromValue = [self.layer valueForKeyPath:anim.keyPath];
      [self.layer setValue:@200 forKeyPath:anim.keyPath];
      [self.layer addAnimation:anim forKey:nil];
    }