CAAnimation wiki
CAAnimation
はアニメーション抽象クラスですが、CAAnimation
クラスを直接使用するのではなく、そのサブクラスを使用します.上図に示すように、その家族のサブクラスたちです.CAAnimation
はCAMediaTiming
とCAAction
プロトコルを遵守しています.これはCALayer
に直接作用しています.UIView
ではなく、アニメーションの実行プロセスはメインスレッド上で行われないので、メインスレッドをブロックすることはありません.まずCAnimation
がどのような属性、方法を定義しているかを見てみましょう.+ animation
CAAnimationオブジェクトを初期化+ (instancetype)animation;---
**`CAAnimation`** , `CAAnimation` , , ,`CAAnimation` `CAMediaTiming` `CAAction` , `CALayer` , `UIView` , , 。 `CAnimation` , 。
**`+ animation`** CAAnimation
`+defaultValueForKey:` `- shouldArchiveValueForKey:` , 。 。
**Timing Function (CAMediaTimingFunction)**
Timing Function , Timing Function (Pacing), ( ), , 。
Timing Function `CAMediaTimingFunction`。
@property(nullable, strong) CAMediaTimingFunction *timingFunction;
`CAMediaTimingFunction` , , 。 :
`name` ,`name` :
/** Timing function names. **/
//リニア:均速(速度は変わらず、加速度は0)A_EXTERN NSString * const kCAMediaTimingFunctionLinear __OSX_AVAILABLE_STARTING (__MAC_10_5, __IPHONE_2_0);
//プログレッシブ:アニメーションがゆっくり入って、目的地CA_に加速するEXTERN NSString * const kCAMediaTimingFunctionEaseIn __OSX_AVAILABLE_STARTING (__MAC_10_5, __IPHONE_2_0);
//フェードアウト:動画が全速力で入り、減速して目的地CA_に到着EXTERN NSString * const kCAMediaTimingFunctionEaseOut __OSX_AVAILABLE_STARTING (__MAC_10_5, __IPHONE_2_0);
//漸進漸出:アニメーションがゆっくり入って、中間加速して、減速して目的地に着く.これは既定のアニメーション動作CA_EXTERN NSString * const kCAMediaTimingFunctionEaseInEaseOut __OSX_AVAILABLE_STARTING (__MAC_10_5, __IPHONE_2_0);
CA_EXTERN NSString * const kCAMediaTimingFunctionDefault __OSX_AVAILABLE_STARTING (__MAC_10_6, __IPHONE_3_0);
:(Ease )
* Ease in (`kCAMediaTimingFunctionEaseIn`
):
![](http://upload-images.jianshu.io/upload_images/276769-8e66fc4e8369fc4c.gif?imageMogr2/auto-orient/strip)
* Ease out (`kCAMediaTimingFunctionEaseOut`
):
![](http://upload-images.jianshu.io/upload_images/276769-97bc05022596c53a.gif?imageMogr2/auto-orient/strip)
* Ease in ease out (`kCAMediaTimingFunctionEaseInEaseOut`
):
![](http://upload-images.jianshu.io/upload_images/276769-25bc023663bf848e.gif?imageMogr2/auto-orient/strip)
* (kCAMediaTimingFunctionDefault
):
![](http://upload-images.jianshu.io/upload_images/276769-8de7f89e5091e4cd.gif?imageMogr2/auto-orient/strip)
**cubic-bezier() **
`+ functionWithControlPoints::::` `- initWithControlPoints::::` (cubic-bezier() )。
cubic-bezier() (cubic Bézier curves)。 , , (easing functions)。
( kCAMediaTimingFunctionDefault):
![](http://upload-images.jianshu.io/upload_images/276769-51a4a967a8e54563.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
x(t) 0.0-1.0, t 0.0-1.0, , , , 。
x(t) , t 。
( , (0,0)), 。
** x(t) , v = dx/dt , a = dv/dt( )。** : ( ), , 。 v<0 x(t) , , 。
, Bézier curve ( )
1962 , Pierre Bézier , 。 Paul de Casteljau 1959 de Casteljau , 。
`+ functionWithControlPoints::::` `- initWithControlPoints::::` , ,P0、P1、P2 P3。P0 P3 , , , 。P0(0, 0) ,P3 (1,1), 。 P1 , P2 。
![](http://upload-images.jianshu.io/upload_images/276769-8afe20d291d93a77.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
,*t* [0,1]
![Bézier_3](http://upload-images.jianshu.io/upload_images/276769-75f690bd96dcf78e.gif?imageMogr2/auto-orient/strip)
, , http://cubic-bezier.com/ 。
![ ](http://upload-images.jianshu.io/upload_images/276769-4a77b31566eaa5f3.gif?imageMogr2/auto-orient/strip)
`removedOnCompletion` `CAAnimation` `CABasicAnimation` 。
@property(getter=isRemovedOnCompletion) BOOL removedOnCompletion;
**`CAAnimationDelegate`**
//動画が始まると呼び出される
//動画終了時に呼び出される
##CAPropertyAnimation
`CAPropertyAnimation` `CAAnimation` ,`CAAnimation` , ,`CAPropertyAnimation` 。
`CAPropertyAnimation` `CABasicAnimation` `CAKeyframeAnimation`, `CAPropertyAnimation`。
animation , `
keyPath`。
@property(nullable, copy) NSString *keyPath;
`keyPath` ** The key-path describing the property to be animated.** keyPath `layer` , KeyPath , keyPath `layer` 。
,`layer` ? , `CALayer ` **API** :
/** Geometry and layer hierarchy properties. **/
/* The bounds of the layer. Defaults to CGRectZero. Animatable. */
@property CGRect bounds;
`Animatable` 。
, layer :
`layer` ,
> * model layer tree ( )
> * presentation tree ( )
> * render tree ( )
layer ,model layer tree , render tree ,presentation tree layer 。
`model layer tree` `layer` `layer`, layer , model layer tree。
view1.layer.anchorPoint = CGPointMake(0.6, 0.6);
refer tree( ) , , 。
@property(getter=isAdditive) BOOL additive;
NO, YES , Core Animation presentation layer model layer 。
:http://ronnqvi.st/multiple-animations/ 。
@property(getter=isCumulative) BOOL cumulative;
`cumulative` `repeatCount`( ) , `cumulative` YES , , ,`cumulative` YES NO。
![cumulative = YES](http://upload-images.jianshu.io/upload_images/276769-c7f9f9f814cafa91.gif?imageMogr2/auto-orient/strip)
![cumulative = NO](http://upload-images.jianshu.io/upload_images/276769-2dba8092054ff1b0.gif?imageMogr2/auto-orient/strip)
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position.x"];
animation.fromValue = @25;
animation.toValue = @100;
//
animation.repeatCount = 3;
//アニメーションの持続時間animation.duration = 1; animation.cumulative = NO; animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault]; [_icon.layer addAnimation:animation forKey:@"animation"];
##CABasicAnimation
`CABasicAnimation` `CAPropertyAnimation ` `animationWithKeyPath:` `CABasicAnimation` , layer( Animatable ) 。
###CAMediaTiming
`CAMediaTiming` `CAAnimation`,`CALayer` , 。`CAMediaTiming` , 。
@property CFTimeInterval beginTime;
, :`animation.beginTime = CACurrentMediaTime() +?`。
@property CFTimeInterval duration;
` ` , `HUGE_VALF`。
@property float speed;
`speed` , 1.0, `speed` , `duration /speed`, 0 。
@property CFTimeInterval timeOffset;
`timeOffset` `speed` ,`timeOffset` ,`timeOffset` , 。
** timeOffset = Duration > timeOffset ? timeOffset : (Duration % timeOffset)**
, timeOffset , , ( timeOffset = 3.0 , Duration = 6.0; 3 , 0 ~ 3 )。
![timeOffset = 3.0 , Duration = 6.0](http://upload-images.jianshu.io/upload_images/276769-1520d91e16a584d9.gif?imageMogr2/auto-orient/strip)
//自分でテストして、repeatCountを設定して効果を見ることもできますし、speedの値を設定することもできます.CABasicAnimation*animation=[CABasicAnimation animationWithKeyPath:@"position.x";animation.duration = 6; animation.fromValue = @25; animation.toValue = @225; animation.timeOffset = 3; animation.removedOnCompletion = NO; animation.fillMode = kCAFillModeBackwards; [_icon.layer addAnimation:self.animation2 forKey:@"animation2"];
@property float repeatCount;
( ) , 0。
@property CFTimeInterval repeatDuration;
,`duration` , , 0, `repeatCount` 。
@property BOOL autoreverses;
, NO。
@property(copy) NSString *fillMode;
fillModel: 。 , `removeOnCompletion` NO 。
`removeOnCompletion`: , YES, layer , layer 。
layer : layer , , presentation layer , presentation layer , layer , ,presentation layer layer , , 。
KCAFillModelRemoved , , layer , ,layer , beginTime ( beginTime, )。
![KCAFillModelRemoved](http://upload-images.jianshu.io/upload_images/276769-73a6454a3db7f103.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
KACFillModelForwards ,layer 。
![KACFillModelForwards](http://upload-images.jianshu.io/upload_images/276769-2de1257bf05da36c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
KCAFillModeBackwards , beginTime 。
![KCAFillModeBackwards](http://upload-images.jianshu.io/upload_images/276769-5cc188ba945d85d1.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
KCAFillModeBoth ,layer , layer 。
![KCAFillModeBoth](http://upload-images.jianshu.io/upload_images/276769-599f559edd7f06c2.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
`CAMediaTiming ` , `CABasicAnimation ` layer 。
@property(nullable, strong) id fromValue;
@property(nullable, strong) id toValue;
@property(nullable, strong) id byValue;
`fromValue`: KeyPath layer 。
`toValue`: keyPath layer 。
, `duration` ,keyPath layer fromValue toValue。
`byValue` , layer `position.x` , `fromeValue = @100;` `byValue = @100;` layer `position.x` 100 , `position.x` 100,`position.x` 100 200。
`toValue` `byValue` , 。
`CABasicAnimation`
##CAKeyframeAnimation
(keyframe) , Core Animation 。
`CAKeyframeAnimation` `CABasicAnimation` `CAPropertyAnimation` :
`CABasicAnimation`: `keyPath` `layer` (Animatable) , (fromValue) (toValue)。
`CAKeyframeAnimation`: ` NSArray *values`, ( ), `NSArray *keyTimes` 。
@property(nullable, copy) NSArray *values;
(keyframe) , (duration) , values 。
@property(nullable, copy) NSArray *keyTimes;
, `NSNumber` , 0 0.1( duration ),keyTimes values , keyTimes `KeyTimes = @[]`, 。
** `keyTimes` , , `@(1/7)` `3/7` `@(4/9)` , , , **。
![keyframe](http://upload-images.jianshu.io/upload_images/276769-24f49d490299f282.gif?imageMogr2/auto-orient/strip)
CAKeyframeAnimation * keyframeAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position.x"];
keyframeAnimation.values = @[@(WIDTH/2 - 35) , @(WIDTH/2+35) , @(WIDTH/2 - 35) , @(WIDTH/2+35) , @(WIDTH/2 - 35),@(WIDTH/2+35), @(WIDTH/2 - 35),@(WIDTH/2)];
keyframeAnimation.keyTimes = @[@0, @(0.1), @(0.2), @(0.3),@(0.4),@(0.5) ,@(0.7),@1 ];
keyframeAnimation.duration = 3;
[icon.layer addAnimation:self.keyframeAnimation forKey:@"keyfra
meAnimation"];
@property(nullable) CGPathRef path;
`CAKeyframeAnimation` , , `UIBezierPath`,`UIBezierPath` `CGPathRef` 。
###UIBezierPath
`UIBezierPath` , , 。
`UIBezierPath` :
* 1 . `CAKeyAnimation` , 。
* 2 . `- (void)drawRect:(CGRect)rect` 。
* 3 . `CAShapeLayer` , `CAShapeLayer` ,`CAShapeLayer` 。
`CAKeyAnimation` 。
UIBezierPath
- (instancetype)bezierPathWithRect:(CGRect)rect;
![bezierPathWithRect](http://upload-images.jianshu.io/upload_images/276769-17ac311958269662.gif?imageMogr2/auto-orient/strip)
UIBezierPath *bezierPath = [UIBezierPath bezierPathWithRect:CGRectMake(100, 100 , (WIDTH - 100) / 2, 200)];
CAKeyframeAnimation *keyFrameAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
keyFrameAnimation.duration = 2.0;
keyFrameAnimation.repeatCount = 3;
keyFrameAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
keyFrameAnimation.fillMode = kCAFillModeForwards;
[_icon.layer addAnimation:keyFrameAnimation forKey:@"keyFrameAnimation"];
- (instancetype)bezierPathWithOvalInRect:(CGRect)rect;
![ ](http://upload-images.jianshu.io/upload_images/276769-72979c42987b8c37.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![ .gif](http://upload-images.jianshu.io/upload_images/276769-9b19fa453b3e56af.gif?imageMogr2/auto-orient/strip)
UIBezierPath *bezierPath2 = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(100, 100, (WIDTH - 100)/2, 200)];
keyFrameAnimation.path = bezierPath2.CGPath;
[_icon.layer addAnimation:keyFrameAnimation forKey:@"keyFrameAnimation"];
- (instancetype)bezierPathWithRoundedRect:(CGRect)rect
cornerRadius:(CGFloat)cornerRadius;
![bezierPathWithRoundedRect:
cornerRadius:
](http://upload-images.jianshu.io/upload_images/276769-fb39196f7f521ea0.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![bezierPathWithRoundedRect:
cornerRadius:
](http://upload-images.jianshu.io/upload_images/276769-ef62bc07666a9087.gif?imageMogr2/auto-orient/strip)
CGRect frame = CGRectMake(WIDTH/2 - 100, 150, 200, 200);
UIBezierPath *bezierPath = [UIBezierPath bezierPathWithRoundedRect:frame cornerRadius:65];
keyFrameAnimation.path = bezierPath.CGPath;
[_icon.layer addAnimation:keyFrameAnimation forKey:@"keyFrameAnimation"];
- (instancetype)bezierPathWithRoundedRect:(CGRect)rect
byRoundingCorners:(UIRectCorner)corners
cornerRadii:(CGSize)cornerRadii;
** **
`rect`: frame
`corners`: , , , 、 、 、 、 。
typedef NS_OPTIONS(NSUInteger, UIRectCorner) {
UIRectCornerTopLeft = 1 << 0,
UIRectCornerTopRight = 1 << 1,
UIRectCornerBottomLeft = 1 << 2,
UIRectCornerBottomRight = 1 << 3,
UIRectCornerAllCorners = ~0UL
};
cornerRadii:(CGSize)cornerRadii
***cornerRadii CGSize , , , (2a), (2b), height( ) , width , = width , , , ***
![](http://upload-images.jianshu.io/upload_images/276769-c2b5d8fa8e7daa58.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
** height ,
layer.cornerRadius **
- (instancetype)bezierPathWithArcCenter:(CGPoint)center
radius:(CGFloat)radius
startAngle:(CGFloat)startAngle
endAngle:(CGFloat)endAngle
clockwise:(BOOL)clockwise;
。
center:
radius:
startAngle:
endAngle:
clockwise: ,YES ,NO
** startAngel endAngel 45 , 30 ,startAngel endAngel , 2πr/r=2π,360° =2π , 30 , 90 , M_PI π。**
![](http://upload-images.jianshu.io/upload_images/276769-c70d9b73779a2da4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
iOS devlop , 。
![](http://upload-images.jianshu.io/upload_images/276769-0992faecc25bbbf5.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
。
(instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.backgroundColor = ColorWithHexValue(0x5EB35F);
}
return self;
}
-
(void)drawRect:(CGRect)rect
{
//
[ColorWithHexValue(0xE9816D) setStroke];
// bezier
UIBezierPath bezierPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(100, 100) radius:30 startAngle:0 endAngle:1.5M_PI clockwise:YES];
//
bezierPath.lineWidth = 1;
//
[bezierPath stroke];
}
:
![](http://upload-images.jianshu.io/upload_images/276769-bf0a5e12ab3ab325.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
Path :
- (void)moveToPoint:(CGPoint)point
point , Path 。
- (void)addLineToPoint:(CGPoint)point
point, point 。
-(void)addArcWithCenter:(CGPoint)center
radius:(CGFloat)radius
startAngle:(CGFloat)startAngle
endAngle:(CGFloat)endAngle
clockwise:(BOOL)clockwise
。
- (void)addCurveToPoint:(CGPoint) controlPoint1:(CGPoint)controlPoint1 controlPoint2:(CGPoint)controlPoint2
。
- (void)addCurveToPoint:(CGPoint) controlPoint1:(CGPoint)controlPoint1 controlPoint2:(CGPoint)controlPoint2
。
, , , , , 。
UIBezierPath , , 。
`@interface CAKeyframeAnimation : CAPropertyAnimation`
`calculationMdel` , , anchortPoint position , , , ,calculationMdel :
** **: , . , , , : 。
CA_EXTERN NSString * const kCAAnimationLinear
__OSX_AVAILABLE_STARTING (__MAC_10_5, __IPHONE_2_0);
CA_EXTERN NSString * const kCAAnimationDiscrete
__OSX_AVAILABLE_STARTING (__MAC_10_5, __IPHONE_2_0);
CA_EXTERN NSString * const kCAAnimationPaced
__OSX_AVAILABLE_STARTING (__MAC_10_5, __IPHONE_2_0);
CA_EXTERN NSString * const kCAAnimationCubic
__OSX_AVAILABLE_STARTING (__MAC_10_7, __IPHONE_4_0);
CA_EXTERN NSString * const kCAAnimationCubicPaced
__OSX_AVAILABLE_STARTING (__MAC_10_7, __IPHONE_4_0);
**kCAAnimationLinear**: calculationModel , , ;
**kCAAnimationDiscrete**: , , ;
**kCAAnimationPaced**: , keyTimes , keyTimes timeFunctions ;
**kCAAnimationCubic** , `tensionValues`,`continuityValues`,`biasValues` , ;
**kCAAnimationCubicPaced**: **kCAAnimationCubic** , , , keyTimes timingFunctions 。
![calculationMdel.png](http://upload-images.jianshu.io/upload_images/276769-b3139a444759bf21.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
@property(nullable, copy) NSArray *tensionValues;
@property(nullable, copy) NSArray *continuityValues;
@property(nullable, copy) NSArray *biasValues;
, , , 。
@property(nullable, copy) NSString *rotationMode;
**rotationModel** :
CA_EXTERN NSString * const kCAAnimationRotateAuto
CA_AVAILABLE_STARTING (10.5, 2.0, 9.0, 2.0);
CA_EXTERN NSString * const kCAAnimationRotateAutoReverse
CA_AVAILABLE_STARTING (10.5, 2.0, 9.0, 2.0);
, , 。
![kCAAnimationRotateAuto.gif](http://upload-images.jianshu.io/upload_images/276769-173f59186228680a.gif?imageMogr2/auto-orient/strip)
![kCAAnimationRotateAutoReverse.gif](http://upload-images.jianshu.io/upload_images/276769-ab2af1575b4fe1f3.gif?imageMogr2/auto-orient/strip)
##@interface CASpringAnimation : CABasicAnimation
**CASpringAnimation** **CABasicAnimation** , **CABasicAnimation** , **CASpringAnimation** 。
*** CASpringAnimation iOS9 , APP , iOS9 , iOS7, POP。***
@property CGFloat mass;
, , , , , 0, 1。
@property CGFloat stiffness;
( ), 0, 100。 ,k , , " ", ( ) 。
@property CGFloat damping;
, 0, 10。
** ** , 、 ) / , 。
, , , , , , , , , , , 。
![ ](http://upload-images.jianshu.io/upload_images/276769-5d8867f525d87496.gif?imageMogr2/auto-orient/strip)
@property CGFloat initialVelocity;
, 0, , 。
@property(readonly) CFTimeInterval settlingDuration;
, spring , 。
CASpringAnimation *springAnimation = [CASpringAnimation animationWithKeyPath:@"position.x"];
springAnimation.fromValue = @100;
springAnimation.toValue = @150;
springAnimation.mass = 100.0;
springAnimation.stiffness = 100.0;
springAnimation.damping = 100.0;
springAnimation.initialVelocity = 10;
springAnimation.repeatCount = 3;
springAnimation.fillMode = kCAFillModeRemoved;
[_icon.layer addAnimation:springAnimation forKey:@"springAnimation"];
![springAnimation](http://upload-images.jianshu.io/upload_images/276769-fc52fc9ccd146414.gif?imageMogr2/auto-orient/strip)
:
[https://objccn.io/issue-12-1/](https://objccn.io/issue-12-1/)
https://developer.mozilla.org/zh-CN/docs/Web/CSS/timing-function
http://geeklu.com/2012/09/animation-in-ios/
, , , , 。