UIView.layer.presentationLayer返回最终值(而不是当前值)

时间:2014-03-30 07:38:11

标签: ios objective-c uiview core-animation calayer

这里是 UIView子类中的一些相关代码:

- (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;
}

当动画运行时我使用[self currentX]时,我会得到200(结束值),而不是> 0之间的值(起始值) )和200。是的,用户可以看到动画,所以我真的很困惑。

以下是我拨打doMyCoolAnimation:的代码,以及1秒后的currentX

[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]);
});

有什么想法吗?

3 个答案:

答案 0 :(得分:2)

我不知道在动画代码中使用KVC setter的想法来自哪里,但这就是动画本身的用途。您基本上是告诉图层树使用此行立即更新到新位置:

[self.layer setValue:@200 forKeyPath:anim.keyPath];

然后想知道为什么图层树不会使用没有起始值或结束值的动画为该位置设置动画。动画没什么!根据需要设置动画的toValuefromValue,然后抛弃二传手。或者,如果您希望使用隐式动画,请保留设置器,但通过更改图层的speed来放弃动画并设置其持续时间。

答案 1 :(得分:1)

正如CodaFi所说,你创建动画的方式是错误的。

使用显式动画,使用CABasicAnimation,或通过直接更改图层属性而不使用CAAnimation对象来使用隐式动画。不要混淆两者。

创建CABasicAnimation对象时,在动画上使用setFromValue和/或setToValue。然后动画对象负责动画表示层中的属性。

答案 2 :(得分:1)

我的UIView的图层的presentationLayer没有给我当前的值。它反过来给了我动画的最终值。

要解决这个问题,我所要做的就是添加......

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

...到我的doMyCoolAnimation方法之前我将结束值设置为:

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

所以最后,doMyCoolAnimation看起来像这样:

- (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];
}