当我在animationDidStart中设置结束值时,CABasicAnimation没有插值:
Posted
技术标签:
【中文标题】当我在animationDidStart中设置结束值时,CABasicAnimation没有插值:【英文标题】:CABasicAnimation not interpolating when I set the end value in animationDidStart: 【发布时间】:2014-03-02 02:28:59 【问题描述】:我已经为 CABasicAnimation 实例的紧凑创建做了一个包装器。
它通过 UIView 的类别作为名为 change:from:to:in:ease:delay:done:
的实例方法来实现。例如,我可以这样做:
[self.logo
change:@"y"
from:nil // Use current self.logo.layer.position.y
to:@80
in:1 // Finish in 1000 ms
ease:@"easeOutQuad" // A selector for a CAMediaTimingFunction category method
delay:0
done:nil];
问题
当 CABasicAnimation 启动时,animationDidStart:
处理将 self.logo.layer.position.y
设置为 80(结束值)。在它像这样工作之前,我尝试使用animationDidStop:finished:
做同样的事情,但在完成动画后发现图层闪烁。 现在,图层直接到达最终值,不会发生插值。我在 UIView 类别中实现了animationDidStart:
,如下所示:
- (void)animationDidStart:(CAAnimation *)animation
[self.layer
setValue:[animation valueForKey:@"toValue"]
forKeyPath:[animation valueForKey:@"keyPath"]];
我设置结束值是为了使模型层与表示层匹配(换句话说,防止重置回开始位置)。
这是change:from:to:in:ease:delay:done:
的实现...
- (CABasicAnimation*) change:(NSString*)propertyPath
from:(id)from
to:(id)to
in:(CGFloat)seconds
ease:(NSString*)easeName
delay:(CGFloat)delay
done:(OnDoneCallback)done
NSString* keyPath = [app.CALayerAnimationKeyPaths objectForKey:propertyPath];
if (keyPath == nil) keyPath = propertyPath;
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:keyPath];
if (delay > 0) animation.beginTime = CACurrentMediaTime() + delay;
if (easeName != nil) animation.timingFunction = [CAMediaTimingFunction performSelector:NSSelectorFromString(easeName)];
if (from != nil) animation.fromValue = from;
animation.toValue = to;
animation.duration = seconds;
animation.delegate = self;
[self.layer setValue:done forKey:@"onDone"];
[self.layer addAnimation:animation forKey:keyPath];
return animation;
在上面代码的第一行,这是我用来将属性快捷方式转换为真正的keyPath的NSDictionary。这样我就可以每次只输入@"y"
而不是@"position.y"
。
app.CALayerAnimationKeyPaths = @
@"scale": @"transform.scale",
@"y": @"position.y",
@"x": @"position.x",
@"width": @"frame.size.width",
@"height": @"frame.size.height",
@"alpha": @"opacity",
@"rotate": @"transform.rotation"
;
有什么问题吗?
【问题讨论】:
【参考方案1】:我认为,您所看到的是预期的行为。在该属性的动画开始后,您正在设置一个动画属性。这实际上是最常见和推荐的方式来准确地完成您所看到的事情,即取消动画并立即跳到最终位置。所以你故意在动画开始的那一刻取消你自己的动画。
如果这不是您想要的,请不要这样做。只需将动画属性设置为其最终值之前将动画附加到图层 - 当然要小心,不要在这样做时触发隐式动画。
【讨论】:
所以你是说我应该把[self.layer setValue:to forKeyPath:keyPath];
放在[self.layer addAnimation:animation forKey:keyPath];
之前?
请参阅我的书,了解设置 CABasicAnimation 的规范方法以及它为何如此工作:apeth.com/iosBook/ch17.html#_using_a_cabasicanimation
之前不一定要正确。无论如何,在运行循环结束之前什么都不会发生。可能是您在方法中做的第一件事。其实如果是这样就更简单了,因为这样你就已经把模型层和表现层都设置好了,你就不需要设置from值和to值了。
当我想更改 layer.position.y
时,我仍然看不到插值。我只能通过layer.position
制作动画吗?
也许您只是对模板代码感到困惑。以正常方式尝试:NSString* key = @"position.y"; [self.lay setValue:@200 forKeyPath:key]; CABasicAnimation* ba = [CABasicAnimation animationWithKeyPath:key"]; ba.duration = 3; [self.lay addAnimation:ba forKey:key];
工作正常。以上是关于当我在animationDidStart中设置结束值时,CABasicAnimation没有插值:的主要内容,如果未能解决你的问题,请参考以下文章
当我在代码中设置属性时,情节提要选项是启用还是禁用是不是重要?
使用javascript在谷歌道路API中设置开始和结束位置
为啥 UIScrollView contentSize 在 IB 中被忽略,但当我在 viewDidAppear 方法中设置它时有效?
当我在构建选项中设置 iPhone 开发人员代码签名身份时,为啥 XCode 会继续尝试安装临时配置文件?