隐式动画
- 什么是隐式动画?
每一个UIView内部都默认有着一个CALayer,称之为Root Layer(根层),而所有的非Root Layer,即手动创建的CALayer对象都默认存在着隐式动画,当对这些手动创建的CALayer的部分属性进行修改时,就会默认产生一些动画效果,而这些属性则称之为可动画属性--Animatable Properties。例如:bounds、backgroundColor、position等都是动画属性。
当然,默认的隐式动画也可以通过CATransaction来关闭:
[CATransaction begin];
[CATransaction setDisableActions:YES];
self.myview.layer.position = CGPointMake(10, 10);
[CATransaction commit];
这里CALayer有两个非常重要的属性:
@property CGPoint position;
@property CGPoint anchorPoint;
-
position
属性:用来设置CALayer在分层中的位置,以父层的左上角为原点。 -
anchorPoint
属性:锚点,是描述CALayer自身的,决定着CALayer上哪个点定位在position属性所在的父层的位置,以自身的左上角为原点,默认为CALayer的中点(0.5,0.5),注意锚点的x、y取值范围为0~1。
隐式动画举例:
- 效果:
- 实现代码:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[CATransaction begin];
//设置事务有没有动画
[CATransaction setDisableActions:NO];
//设置事务动画的执行时长.
[CATransaction setAnimationDuration:1];
self.layer.bounds = CGRectMake(0, 0, arc4random_uniform(200), arc4random_uniform(200));
self.layer.position = CGPointMake(arc4random_uniform(300), arc4random_uniform(400));
self.layer.backgroundColor = [self randomColor].CGColor;
self.layer.cornerRadius = arc4random_uniform(50);
[CATransaction commit];
}
- (UIColor *)randomColor{
CGFloat r = arc4random_uniform(256) /255.0;
CGFloat g = arc4random_uniform(256) /255.0;
CGFloat b = arc4random_uniform(256) /255.0;
return [UIColor colorWithRed:r green:g blue:b alpha:1];
}
核心动画
这里主要介绍iOS的几种核心动画。
- 基本动画
- 关键帧动画
- 动画组
- 转场动画
核心动画(Core Animation)的动画执行过程都是在后台线程操作的,不会阻塞主线程。
动画的继承关系如下图:
核心动画的使用步骤:
- 首先要有一个CALayer
- 初始化一个CAAnimation对象,设置相关动画属性
- 调用CALayer的
addAnimation:forKey:
方法,将CAAnimation对象添加到CALayer中,开始动画 - 调用CALayer的
removeAnimationForKey:
方法可停止CALayer中的动画
注意:CAAnimation是所有动画对象的父类,负责控制动画的持续时间和速度,是个抽象类,不能直接使用,需使用它的子类。CAAnimation的CAPropertyAnimation子类,也是抽象类,不可直接使用,需使用它的两个子类CABasicAnimation和CAKeyframeAnimation。
使用效果
CABasicAnimation
- 效果
- 实现代码:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
CABasicAnimation *anim = [CABasicAnimation animation];
anim.keyPath = @"position";
anim.toValue = [NSValue valueWithCGPoint:CGPointMake(200, 400)];
anim.removedOnCompletion = NO;
//保存动画最前面效果
anim.fillMode = kCAFillModeForwards;
[self.redView.layer addAnimation:anim forKey:nil];
}
CAKeyframeAnimation
- 效果:
- 实现代码:
CAKeyframeAnimation *anim = [CAKeyframeAnimation animation];
anim.keyPath = @"position";
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(140, 100)];
[path addLineToPoint:CGPointMake(160, 100)];
anim.path = path.CGPath;
anim.repeatCount = MAXFLOAT;
anim.autoreverses = YES;
anim.duration = 1;
[self.iconV.layer addAnimation:anim forKey:nil];
CATransition
- 效果:
- 实现代码:
typedef enum : NSUInteger {
Fade = 1, //淡入淡出
Push, //推挤
Reveal, //揭开
MoveIn, //覆盖
Cube, //立方体
SuckEffect, //吮吸
OglFlip, //翻转
RippleEffect, //波纹
PageCurl, //翻页
PageUnCurl, //反翻页
CameraIrisHollowOpen, //开镜头
CameraIrisHollowClose, //关镜头
CurlDown, //下翻页
CurlUp, //上翻页
FlipFromLeft, //左翻转
FlipFromRight, //右翻转
} AnimationType;
- (void)CATransition{
//转场代码必须得要和转场动画在同一个方法当中.
//创建动画
CATransition *anim = [CATransition animation];
//设置转场类型
anim.type = @"pageCurl";
//设置转场的方向
anim.subtype = kCATransitionFromTop;
//设置动画的开始点.
anim.startProgress = 0.2;
//设置动画的结束点.
anim.endProgress = 0.8;
anim.duration = 1;
[self.imageV.layer addAnimation:anim forKey:nil];
}
CAAnimationGroup
- 效果:
- 实现代码:
-(void)touchesBegan:(nonnull NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event{
CAAnimationGroup *group = [CAAnimationGroup animation];
//缩放
CABasicAnimation *scaleAnim = [CABasicAnimation animation];
//设置属性
scaleAnim.keyPath = @"transform.scale";
scaleAnim.toValue = @0.5;
//平移
CABasicAnimation *Anim = [CABasicAnimation animation];
//设置属性
Anim.keyPath = @"position.y";
Anim.toValue = @(400);
group.animations = @[scaleAnim,Anim];
group.removedOnCompletion = NO;
group.fillMode = kCAFillModeForwards;
//添加动画
[self.redView.layer addAnimation:group forKey:nil];
}
这里要区分好UIView动画和核心动画的使用场景,核心动画只作用在layer,核心动画修改的值都是假像,它的真实位置没有发生变化。需要交互的用UIView,不需要进行交互时两个都可以使用。