我爲CABasicAnimation實例的緊湊創建制作了一個包裝。 它通過一個名爲change:from:to:in:ease:delay:done:
的實例方法通過UIView類別實現。因此,例如,我可以這樣做:當我在animationDidStart中設置最終值時,CABasicAnimation沒有插值:
[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;
}
在上面的代碼中的第一行,這是我的NSDictionary使用屬性的快捷方式轉換爲真正的keyPath。這樣我就可以每次輸入@"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"
};
還有問題嗎?
所以你說我應該把'[self.layer setValue:forKeyPath:keyPath];''在'[self.layer addAnimation:animation forKey:keyPath]之前';'? – aleclarson
請參閱我的書,以建立CABasicAnimation的規範方式以及爲什麼它按照以下方式工作:http://www.apeth.com/iOSBook/ch17.html#_using_a_cabasicanimation – matt
不需要在_right_之前。無論如何,直到運行循環結束,纔會發生任何事情。可能是你在你的方法中做的第一件事。事實上,它更簡單,因爲這樣你就可以建立模型層和表示層,並且不需要設置from值和value值。 – matt