五.隐式动画(手动创建的CALayer才有隐式动画):也就是说自带动画,不需要加animation
- 每一个
UIView
内部都默认连着一个CALayer
,我们可用称这个Layer
为RootLayer
(根层) - 所有的非
Root Layer
,也就是手动创建的CALayer
对象,都存在隐式动画
下面以一个clayer的旋转为例
旋转一般会用到 角度转弧度: 角度/180.0*M_PI
宏定义: #define angle2radion(angle) ((angle) / 180.0 * M_PI)
重点提一下:旋转的中心: layer.anchorPoint = CGPointZero;
anchorPoint的范围是(0~1,0~1);
隐式动画代码 密码: icgj
切记:非根层才能建立隐式动画(也就是自定义的CALayer)
六.时钟的制作
晓效果图如下:
在涉及到旋转的时候我们首先要确定的是它的锚点,其次是position
这里主要是运用了1.隐式动画.2.角度转弧度.3.再就是一些旋转的设置
角度转弧度 #define angle2radion(angle) ((angle) / 180.0 * M_PI)
时钟的代码:里面有中详细的注释 密码: b2c8
在此多数几句:如何获取系统的时间
//获取当前的系统时间 //获取当前日历对象 NSCalendar *calendar =[NSCalendar currentCalendar]; //获取日期的组件,年月日,时分秒 //components: 需要获取日期组件 //formDate:获取哪个日期组件 //经验:以后枚举中有移位运算符(<<),一般来说我们就可以用 | :"并" 的方式 NSDateComponents *dateComponents = [calendar components:NSCalendarUnitSecond | NSCalendarUnitMinute | NSCalendarUnitHour | NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear fromDate:[NSDate date]];
NSLog(@"小时==%ld",dateComponents.hour);
NSLog(@"分钟==%ld",dateComponents.minute);
NSLog(@"秒==%ld",dateComponents.second);
七.核心动画(介绍四个,CABasicAnimation
, CAKeyframeAnimation
, CATransition
, CAAnimationGroup
)
- <1>.
Core Animation
中文翻译为核心动画,它是一组非常强大的动画处理API
,使用它可以做出非常炫酷的效果,而且往往是事半功倍,也就是说,使用少量的代码就可以实现非常强大的功能. - <2>.
Core Animation
可以使用在Mac OS X
和iOS
平台. - <3>.
Core Animation
的动画执行过程都是在后台操作的,不会阻塞主线程. - <4>.需要注意的是:
Core Animation
是直接作用在CALayer
上的,并非UIView
.在此也说一下UIView
也有动画,其实也是在底层封装了核心动画
(1)CABasicAnimation创建动画(这里仅仅以一个view的移动为例):只能用于2个值之间
/** * CABasicAnimation创建核心动画 */ -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { //创建动画 CABasicAnimation *animation = [CABasicAnimation animation]; //描述下修改那个属性产生动画 animation.keyPath = @"position"; //设置值(点转化为对象) animation.toValue = [NSValue valueWithCGPoint:CGPointMake(arc4random_uniform(500), arc4random_uniform(500))]; //取消动画反弹需要2步 //1.设置动画完成时候不要移除动画 animation.removedOnCompletion = NO; //2.设置动画执行完成保持最新的效果 animation.fillMode = kCAFillModeForwards; //添加动画 [_redView.layer addAnimation:animation forKey:nil]; }
如果先个缩放就把上面的值改了就好
animation.keyPath = @"transform.scale"; animation.toValue = @0.5;
如果想做一个心脏的话那么久设置一个一直执行动画,也可以调节动画的时间长短,下面的代码放到一个方法里面就好(可以做心脏的跳动)
二维的放大和缩小
_redVie
就是一个UIImageView
的类的对象
//创建动画 CABasicAnimation *animation = [CABasicAnimation animation]; //描述下修改那个属性产生动画 animation.keyPath = @"transform.scale"; //设置值 animation.toValue = @0.5; //设置每次动画的时间 animation.duration = 1; //如果想一直执行动画,很久 animation.repeatCount = MAXFLOAT;//表示最大次数 //取消动画反弹需要2步 //1.设置动画完成时候不要移除动画 animation.removedOnCompletion = NO; //2.设置动画执行完成保持最新的效果 animation.fillMode = kCAFillModeForwards; //添加动画 [_redView.layer addAnimation:animation forKey:nil];
当然我们还可以设置旋转
animation.keyPath = @"transform.rotation"; animation.toValue = @(M_PI*2);//360旋转
- (2).cakeyframeanimation创建帧动画
1.心脏的抖动
代码如下:
//创建动画 CAKeyframeAnimation *animation = [CAKeyframeAnimation animation]; //根据路径来走 animation.keyPath = @"transform.rotation"; //角度的设定 animation.values = @[@angle2radion(-5),@angle2radion(5),@angle2radion(-5)]; //不停地循环来抖动 animation.repeatCount = MAXFLOAT; //添加在图层上的动画 [_heart.layer addAnimation:animation forKey:nil];
当然你也可以设置它的锚点
_heart.layer.anchorPoint = CGPointZero;(以心脏的左上为旋转的点来抖动)
2.让心脏绕着指定轨迹来做运动(用到了贝塞尔曲线
):改变的是位置position
核心代码如下:
//创建动画 CAKeyframeAnimation *animation = [CAKeyframeAnimation animation]; //改变的位置 animation.keyPath = @"position"; //动画执行的时间 animation.duration = 2; //设定转圈的路径 animation.path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(100, 200, 200, 200)].CGPath; //重复动画 animation.repeatCount = MAXFLOAT; //添加动画 [_heart.layer addAnimation:animation forKey:nil];
3.心脏根据画出路径来走
首先要建立一个UIView 也就是图层(画画的地方)
效果如下
心脏根据路径走的代码 密码: dq43
核心代码如下:
@property(nonatomic,strong) UIBezierPath *path; /** * 手指接触屏幕的点 */ -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { //touch UITouch *touch = [touches anyObject]; //获取手指的触摸点 CGPoint pointCurrent = [touch locationInView:self]; //创建路径 UIBezierPath *path = [UIBezierPath bezierPath]; //记录路径 _path = path; //设置起点 [path moveToPoint:pointCurrent]; } /** * 手指一动的时候的点 */ -(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { //touch UITouch *touch = [touches anyObject]; //获取手指的触摸点 CGPoint pointCurrent = [touch locationInView:self]; //保存每一个路径 [_path addLineToPoint:pointCurrent]; //每次一动就调用画画 [self setNeedsDisplay]; } /** * 画线 */ -(void)drawRect:(CGRect)rect { [_path stroke]; } /** * 手指抬起来的时候 */ -(void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { //创建动画 CAKeyframeAnimation *animation = [CAKeyframeAnimation animation]; animation.keyPath = @"position"; animation.duration = 2; animation.path = _path.CGPath; animation.repeatCount = MAXFLOAT; //添加动画 [[[self.subviews firstObject] layer] addAnimation:animation forKey:nil]; }
添加动画
[[[self.subviews firstObject] layer] addAnimation:animation forKey:nil];
注意:我再重复一次,动画式添加在图层上的
- (3).转场动画CATransition
转场动画和转场代码要写在一起:(切记)
效果图如下:
核心代码如下:(转场动画和转场代码要写在一起)
/** * 在触摸时的变化 */ -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { 转场代码 if(i==4) { i = 1; } NSString *imageName = [NSString stringWithFormat:@"%d.jpg",i]; _imageView.image = [UIImage imageNamed:imageName]; i++; 添加转场动画 CATransition *animation = [CATransition animation]; animation.type = @"cube"; animation.duration = 2; [_imageView.layer addAnimation:animation forKey:nil]; }
如果想看其他的效果:可以更改下面的值:
animation.type = @"cube";
转场动画代码密码: ffmy
- (4).动画组(之前的动画只能缩放或者旋转,动画组可以实现旋转和缩放同时进行)
效果如下:
动画组
核心的代码如下:(也就是一个group来包含很多的动画组合起来的)
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { //同时缩放,平移,旋转 CAAnimationGroup *group = [CAAnimationGroup animation]; group.duration = 2; CABasicAnimation *scale = [CABasicAnimation animation]; scale.keyPath = @"transform.scale"; scale.toValue = @0.5; CABasicAnimation *rotation = [CABasicAnimation animation]; rotation.keyPath = @"transform.rotation"; rotation.toValue = @(arc4random_uniform(M_PI)); CABasicAnimation *position = [CABasicAnimation animation]; position.keyPath = @"position"; position.toValue = [NSValue valueWithCGPoint:CGPointMake(arc4random_uniform(200)+100, arc4random_uniform(400)+100)]; group.animations = @[scale,rotation,position]; //取消动画反弹需要2步 //1.设置动画完成时候不要移除动画 group.removedOnCompletion = NO; //2.设置动画执行完成保持最新的效果 group.fillMode = kCAFillModeForwards; [_imageView.layer addAnimation:group forKey:nil]; }
动画组代码 密码: 4yiq
再重复一次:核心动画式加在图层上的
八.UIView与核心动画的区别
注意:
1.核心动画一切都是假象,并不会真实的改变图层的属性值.如果以后做动画的时候,不需要与用户交互,通常用核心动画(转场)
原因:当我们改变一个视图的position的时候,它的position并没有发生改变,大家可以打印一下看看(打印看看)
NSLog(@"%@",NSStringFromCGPoint(_girl.layer.position));
2.UIView动画必须通过修改属性的真实值,才有动画效果
[UIView animateWithDuration:1 animations:^{ } completion:^(BOOL finished) { }];