CABasicAnimation
1. 什么是CABasicAnimation
CABasicAnimation
是核心动画类簇中的一个类,其父类是CAPropertyAnimation
,其子类是CASpringAnimation
,它的祖父是CAAnimation
。
它主要用于制作比较单一的动画,例如,平移、缩放、旋转、颜色渐变、边框的值的变化等,也就是将layer的某个属性值从一个值到另一个值的变化。类似x -> y这种变化,然而对于x -> y -> z甚至更多的变化是不行的。
2. 属性说明
属性 | 说明 |
---|---|
duration | 动画的时长 |
repeatCount | 重复的次数。不停重复设置为 HUGE |
repeatDuration | 设置动画的时间。在该时间内动画一直执行,不计次数。 |
beginTime | 指定动画开始的时间。从开始延迟几秒的话,设置为【CACurrentMediaTime() + 秒数】 的方式 |
autoreverses | 动画结束时是否执行逆动画 |
timingFunction | 设置动画的速度变化 |
duration | 动画的时长 |
fromValue | 所改变属性的起始值 |
toValue | 所改变属性的结束时的值 |
byValue | 所改变属性相同起始值的改变量 |
3.实例化方法
使用方法animationWithKeyPath:
对 CABasicAnimation进行实例化,并指定Layer的属性作为关键路径进行注册。
let animation = CABasicAnimation(keyPath: "transform.rotation.z")
下面是对keypath比较全面的总结,每个keypath对应一种属性值的变化,其中涉及到颜色变化的都必须使用CGColor,因为对应是对layer的属性。
#ifndef AnimationKeyPathName_h
#define AnimationKeyPathName_h
#import <Foundation/Foundation.h>
/* CATransform3D Key Paths */
/* 旋转x,y,z分别是绕x,y,z轴旋转 */
static NSString *kCARotation = @"transform.rotation";
static NSString *kCARotationX = @"transform.rotation.x";
static NSString *kCARotationY = @"transform.rotation.y";
static NSString *kCARotationZ = @"transform.rotation.z";
/* 缩放x,y,z分别是对x,y,z方向进行缩放 */
static NSString *kCAScale = @"transform.scale";
static NSString *kCAScaleX = @"transform.scale.x";
static NSString *kCAScaleY = @"transform.scale.y";
static NSString *kCAScaleZ = @"transform.scale.z";
/* 平移x,y,z同上 */
static NSString *kCATranslation = @"transform.translation";
static NSString *kCATranslationX = @"transform.translation.x";
static NSString *kCATranslationY = @"transform.translation.y";
static NSString *kCATranslationZ = @"transform.translation.z";
/* 平面 */
/* CGPoint中心点改变位置,针对平面 */
static NSString *kCAPosition = @"position";
static NSString *kCAPositionX = @"position.x";
static NSString *kCAPositionY = @"position.y";
/* CGRect */
static NSString *kCABoundsSize = @"bounds.size";
static NSString *kCABoundsSizeW = @"bounds.size.width";
static NSString *kCABoundsSizeH = @"bounds.size.height";
static NSString *kCABoundsOriginX = @"bounds.origin.x";
static NSString *kCABoundsOriginY = @"bounds.origin.y";
/* 透明度 */
static NSString *kCAOpacity = @"opacity";
/* 背景色 */
static NSString *kCABackgroundColor = @"backgroundColor";
/* 圆角 */
static NSString *kCACornerRadius = @"cornerRadius";
/* 边框 */
static NSString *kCABorderWidth = @"borderWidth";
/* 阴影颜色 */
static NSString *kCAShadowColor = @"shadowColor";
/* 偏移量CGSize */
static NSString *kCAShadowOffset = @"shadowOffset";
/* 阴影透明度 */
static NSString *kCAShadowOpacity = @"shadowOpacity";
/* 阴影圆角 */
static NSString *kCAShadowRadius = @"shadowRadius";
#endif /* AnimationKeyPathName_h */
4. 防止动画结束后回到初始状态
只需设置removedOnCompletion
、fillMode
两个属性就可以了。
transformAnima.removedOnCompletion = NO;
transformAnima.fillMode = kCAFillModeForwards;
首先我们需要搞明白一点的是,layer动画运行的过程是怎样的?其实在我们给一个视图添加layer动画时,真正移动并不是我们的视图本身,而是 presentation layer 的一个缓存。动画开始时 presentation layer开始移动,原始layer隐藏,动画结束时,presentation layer从屏幕上移除,原始layer显示。这就解释了为什么我们的视图在动画结束后又回到了原来的状态,因为它根本就没动过。
这个同样也可以解释为什么在动画移动过程中,我们为何不能对其进行任何操作。
所以在我们完成layer动画之后,最好将我们的layer属性设置为我们最终状态的属性,然后将presentation layer 移除掉。
5. 动画开始和结束时的事件
为了获取动画的开始和结束事件,需要实现协议
transformAnima.delegate = self;
//动画开始时
func animationDidStart(_ anim: CAAnimation) {
print("开始了");
}
//动画结束时
func animationDidStop(_ anim: CAAnimation, finished flag: Bool) {
//方法中的flag参数表明了动画是自然结束还是被打断,比如调用了removeAnimationForKey:方法或removeAnimationForKey方法,flag为NO,如果是正常结束,flag为YES。
print(@"结束了");
}
使用方法
let animation = CABasicAnimation(keyPath: "transform.rotation.z")
animation.toValue = rotationAngle + 360 * .pi / 180.0 * CGFloat(num)
animation.duration = CFTimeInterval(num) + 0.5
animation.isCumulative = false
animation.delegate = self
animation.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
animation.fillMode = .forwards
animation.isRemovedOnCompletion = false
rotateView.layer.add(animation, forKey: "rotationAnimation")