一:隐式动画

#import "ViewController.h"

@interface ViewController ()

/** <#注释#> */
@property (nonatomic, weak) CALayer *layer;
@property (weak, nonatomic) IBOutlet UIView *redView; @end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad]; CALayer *layer = [CALayer layer];
layer.backgroundColor = [UIColor redColor].CGColor;
layer.frame = CGRectMake(, , , );
self.layer = layer;
[self.view.layer addSublayer:layer]; } -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { //只有非根层才有隐式动画,(自己手动创建的图片)
[CATransaction begin];
[CATransaction setDisableActions:NO];//此属性可设置关掉隐士动画
[CATransaction setAnimationDuration:];
self.layer.backgroundColor = [UIColor greenColor].CGColor;
[CATransaction commit]; self.layer.bounds = CGRectMake(, , , );
self.layer.backgroundColor = [UIColor greenColor].CGColor;
self.layer.position = CGPointMake(, ); self.redView.layer.position = CGPointMake(, );
self.redView.layer.bounds = CGRectMake(, , , );
self.redView.layer.backgroundColor = [UIColor greenColor].CGColor; } @end

什么是隐式动画?

了解什么是隐式动画前,要先了解是什么根层和非根层.

根层:UIView内部自动关联着的那个layer我们称它是根层.

非根层:自己手动创建的层,称为非根层.

隐式动画就是当对非根层的部分属性进行修改时, 它会自动的产生一些动画的效果.

我们称这个默认产生的动画为隐式动画.

如何取消隐式动画?

首先要了解动画底层是怎么做的.动画的底层是包装成一个事务来进行的.

什么是事务?

很多操作绑定在一起,当这些操作执行完毕后,才去执行下一个操作.

开启事务

[CATransaction begin];

设置事务没有动画

[CATransaction setDisableActions:YES];

设置动画执行的时长

[CATransaction setAnimationDuration:2];

提交事务

[CATransaction commit];

二:时钟效果:

效果如图:

#import "ViewController.h"

//每一秒旋转的度数
#define perSecA 6 //每一分旋转的度数
#define perMinA 6 //每一小时旋转的度数
#define perHourA 30 //每一分,时针旋转的度数
#define perMinHour 0.5 #define angle2Rad(angle) ((angle) / 180.0 * M_PI) @interface ViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *colockView; /** 当前的秒针 */
@property (nonatomic, weak) CALayer *secL;
/** 当前的分针 */
@property (nonatomic, weak) CALayer *minL;
/** 当前的针针 */
@property (nonatomic, weak) CALayer *hourL; @end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad]; //添加时针
[self setHour]; //添加分针
[self setMin];
//添加秒针
[self setSec]; //添加定时器:scheduledTimerWithTimeInterval不用加到runLoop,因为已经默认添加到了runLoop
[NSTimer scheduledTimerWithTimeInterval: target:self selector:@selector(timeChange) userInfo:nil repeats:YES];
//添加的定时器不会立即执行,而是过一秒才会执行,此时可以调用定时器的fire方法,立即执行,也可以手动调用定时器的方法
[self timeChange];
} //第一称调用一次
- (void)timeChange { NSCalendar *cal = [NSCalendar currentCalendar];
//components:日历的组件,年,月,日 ,时,分,秒.
//fromDate:从什么时间开始获取
NSDateComponents *cmp = [cal components:NSCalendarUnitSecond | NSCalendarUnitMinute | NSCalendarUnitHour fromDate:[NSDate date]];
//获取当前多少秒
NSInteger curSec = cmp.second + ; //秒针开始旋转
//计算秒针当前旋转的角度.
//angle = 当前多少秒 * 每一秒旋转多少度.
/**
* CATransform3DMakeRotation:3D旋转:1:必须是在layear层才能进行3D旋转,用transform,旋转的角度为弧度制,2:#define angle2Rad(angle) ((angle) / 180.0 * M_PI) 3:分xyz轴,
*/
CGFloat secA = curSec * perSecA;
self.secL.transform = CATransform3DMakeRotation(angle2Rad(secA), , , ); //获取当前多少秒
NSInteger curMin = cmp.minute;
NSLog(@"%ld",curMin);
//分针开始旋转
//计算分针当前旋转的角度.
//angle = 当前多少分 * 每一分旋转多少度.
CGFloat minA = curMin * perMinA;
self.minL.transform = CATransform3DMakeRotation(angle2Rad(minA), , , ); //获取当前是多少小时
NSInteger curHour = cmp.hour;
NSLog(@"%ld",curMin);
//分针开始旋转
//计算分针当前旋转的角度.
//angle = 当前多少小时 * 每一小时旋转多少度.
CGFloat hourA = curHour * perHourA + curMin * perMinHour;
self.hourL.transform = CATransform3DMakeRotation(angle2Rad(hourA), , , ); } /**
* 1:搭建时针秒针分针的UI效果:1:UIView和CALayear是一样的效果,但是UIView比CALyear多了一个处理点击事件,则CALyear相对于UIView来说更加轻量级,更加高效 2:非根层的layear也就是自己创建的layear都存在隐士动画,要关闭隐式动画,用动画事物CATransaction去关闭:
开启事务 [CATransaction begin]; 设置事务没有动画 [CATransaction setDisableActions:YES]; 设置动画执行的时长 [CATransaction setAnimationDuration:2]; 提交事务 [CATransaction commit]; 3:无论是旋转,缩放都是绕着锚点进行的.也就是默认情况下是绕着中心点center进行的。所以要改变其绕着最后的节点旋转,需要先定义好layear的position,在定义锚点,最后的效果是锚点与point点重合。position的位置为表盘的中心点,锚点的默认位置为0.5 ,0.5,修改表盘的锚点位置让锚点与position点重合,这样旋转的时候就会绕着锚点旋转。再把此layear添加到表盘的layear上。
*
*
*/ //添加秒针
//无论是旋转,缩放都是绕着锚点进行的.
- (void)setSec { CALayer *secL = [CALayer layer];
secL.bounds = CGRectMake(, , , );
secL.backgroundColor = [UIColor redColor].CGColor;
secL.anchorPoint = CGPointMake(0.5, );
secL.position = CGPointMake(self.colockView.bounds.size.width * 0.5, self.colockView.bounds.size.height * 0.5);
[self.colockView.layer addSublayer:secL];
self.secL = secL; } //添加分针
- (void)setMin { CALayer *minL = [CALayer layer];
minL.bounds = CGRectMake(, , , );
minL.backgroundColor = [UIColor blackColor].CGColor;
minL.anchorPoint = CGPointMake(0.5, );
minL.cornerRadius = 1.5;
minL.position = CGPointMake(self.colockView.bounds.size.width * 0.5, self.colockView.bounds.size.height * 0.5);
[self.colockView.layer addSublayer:minL];
self.minL = minL; } //时针
- (void)setHour { CALayer *hourL = [CALayer layer];
hourL.bounds = CGRectMake(, , , );
hourL.backgroundColor = [UIColor blackColor].CGColor;
hourL.anchorPoint = CGPointMake(0.5, );
hourL.cornerRadius = 1.5;
hourL.position = CGPointMake(self.colockView.bounds.size.width * 0.5, self.colockView.bounds.size.height * 0.5);
[self.colockView.layer addSublayer:hourL];
self.hourL = hourL; } //-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
//
// //所有旋转,缩放,都是绕着锚点进行.
// self.secL.transform = CATransform3DMakeRotation(M_PI, 0, 0, 1);
//} @end

1.搭建界面.

分析界面.

界面上时针,分针,秒针不需要与用户进行交互.所以都可以使用layer方式来做.

做之前要观察时针在做什么效果.

是根据当前的时间,绕着表盘的中心点进行旋转.

要了解一个非常重要的知识点.无论是旋转,缩放它都是绕着锚点.进行的.

要想让时针,分针,称针显示的中间,还要绕着中心点进行旋转.

那就要设置它的position和anchorPoint两个属性.

创建秒针

CALayer *layer = [CALayer layer];

_secLayer = layer;

layer.bounds = CGRectMake(0, 0, 1, 80);

layer.anchorPoint = CGPointMake(0.5, 1);

layer.position = CGPointMake(_clockView.bounds.size.width * 0.5, _clockView.bounds.size.height * 0.5);

layer.backgroundColor = [UIColor redColor].CGColor;

[_clockView.layer addSublayer:layer];

2.让秒针开始旋转.

让秒针旋转.所以要计算当前的旋转度是多少?

当前的旋转角度为:当前的时间 * 每秒旋转多少度.

计算每一秒旋转多少度.

60秒转一圈360度

360 除以60就是每一秒转多少度.每秒转6度.

获取当前的时间

创建日历类

NSCalendar *calendar = [NSCalendar currentCalendar];

把日历类转换成一个日期组件

日期组件(年,月,日,时,分,秒)

component:日期组件有哪些东西组成,他是一个枚举,里面有年月日时分秒

fromDate:当前的日期

NSDateComponents *cmp = [calendar components:NSCalendarUnitSecond

fromDate:[NSDate date]];

我们的秒就是保存在日期组件里面,它里面提供了很多get方法.

NSInteger second = cmp.second;

那么当前秒针旋转的角度就是

当前的秒数乘以每秒转多少度.

second * perSecA

还得要把角度转换成弧度.

因为下面分针,时针也得要用到, 就把它抽出一个速参数的宏.

#define angle2Rad(angle) ((angle) / 180.0 * M_PI)

让它每隔一秒旋转一次.所以添加一个定时器.

每个一秒就调用,旋转秒针

- (void)timeChange{

获取当前的秒数

创建日历类

NSCalendar *calendar = [NSCalendar currentCalendar];

把日历类转换成一个日期组件

日期组件(年,月,日,时,分,秒)

component:日期组件有哪些东西组成,他是一个枚举,里面有年月日时分秒

fromDate:当前的日期

NSDateComponents *cmp = [calendar components:NSCalendarUnitSecond

fromDate:[NSDate date]];

我们的秒就是保存在日期组件里面,它里面提供了很多get方法.

NSInteger second = cmp.second;

秒针旋转多少度.

CGFloat angel = angle2Rad(second * perSecA);

旋转秒针

self.secondL.transform = CATransform3DMakeRotation(angel, 0, 0, 1);

}

运行发现他会一下只就调到某一个时间才开始旋转

一开始的时候就要来到这个方法,获取当前的秒数把它定位好.

要在添加定时器之后就调用一次timeChange方法.

3.添加分针

快速拷贝一下,然后添加一个分针成员属性.

修改宽度,修改颜色

也得要让它旋转,

要算出每分钟转多少度

转60分钟刚好是一圈

所以每一分钟也是转6度.

获取当前多少分?

同样是在日期组件里面获得

里面有左移符号,右移符号.他就可以用一个并运算

现在同时让他支持秒数和分 后面直接加上一个 |

NSDateComponents *cmp = [calendar components:NSCalendarUnitSecond |

NSCalendarUnitMinute

fromDate:[NSDate date]];

CGFloat minueteAngel = angle2Rad(minute * perMinuteA);

self.minueL.transform = CATransform3DMakeRotation(minueteAngel, 0, 0, 1);

4.添加时针

同样复制之前的,添加一个小时属性

小时转多少度

当前是多少小时,再计算先每一小时转多少度.

12个小时转一圈. 360除以12,每小时转30度

时针旋转多少度

CGFloat hourAngel = angle2Rad(hour * perHourA);

旋转时针

self.hourL.transform = CATransform3DMakeRotation(hourAngel, 0, 0, 1);

直接这样写会有问题

就是没转一分钟,小时也会移动一点点

接下来要算出,每一分钟,小时要转多少度

60分钟一小时.一小时转30度.

30 除以60,就是每一分钟,时针转多少度.0.5

时针旋转多少度

CGFloat hourAngel = angle2Rad(hour * perHourA + minute * perMinuteHourA);

旋转时针

self.hourL.transform = CATransform3DMakeRotation(hourAngel, 0, 0, 1);

ios开发核心动画三:隐式动画与时钟效果的更多相关文章

  1. iOS动画学习 -隐式动画

    事务 Core Animation基于一个假设,说屏幕上的任何东西都可以(或者可能)做动画.你并不需要在Core Animation中手动打开动画,但是你需要明确地关闭它,否则它会一直存在. 当你改变 ...

  2. iOS:CALayer的隐式动画的详解

    CALayer的隐式动画属性: •每一个UIView内部都默认关联着一个CALayer,称这个Layer为Root Layer.所有的非Root Layer都存在着隐式动画,隐式动画的默认时长为1/4 ...

  3. iOS中的隐式动画

    隐式动画就是指  在 非 人为在代码中 定义动画  而系统却默认  自带   的动画  叫做隐式动画. 比如  改变 图层  的颜色  位置  和   透明度  的时候    都会  产生附带的渐变的 ...

  4. [iOS Animation]-CALayer 隐式动画

    隐式动画 按照我的意思去做,而不是我说的. -- 埃德娜,辛普森 我们在第一部分讨论了Core Animation除了动画之外可以做到的任何事情.但是动画是Core Animation库一个非常显著的 ...

  5. iOS边练边学--CALayer,非根层隐式动画,钟表练习

    一.CALayer UIView之所以能显示在屏幕上,完全是因为他内部的一个图层 在创建UIView对象时,UIView内部会自动创建一个图层(即CALayer对象),通过UIView的layer属性 ...

  6. IOS第18天(3,CALayer隐式动画)

    ******隐式动画(手指拖拽Layer) #import "HMViewController.h" @interface HMViewController () @propert ...

  7. IOS 隐式动画(非Root Layer)

    ● 每一个UIView内部都默认关联着一个CALayer,我们可用称这个Layer为Root Layer(根 层) ● 所有的非Root Layer,也就是手动创建的CALayer对象,都存在着隐式动 ...

  8. CALayer的隐式动画

    CALayer的使用 在我的理解中CALayer就是iOS中利用图层精简非交互式绘图.那么那些核心动画类.也就是变化图层的非交互式绘制规则而已.其中的本质就是将CALayer中的内容转化为map图.从 ...

  9. 非RootLayer的隐式动画

    非RootLayer都有隐式动画,默认0.25秒. // 1.开启 [CATransaction begin]; // 2.设置关闭 YES-关闭:NO-开启 [CATransaction setDi ...

随机推荐

  1. Cocos2d-x 之大牛看法

    (未完毕) cocos2d-x并非一个适合网游client(mmo)的游戏引擎.越是大型游戏,这个小引擎就越无法驾驭(尽管它很受欢迎). 之前我在原来的公司使用的是自主研发的C3引擎,已经对外开放(尚 ...

  2. HDU 3072--Intelligence System【SCC缩点新构图 &amp;&amp; 求连通全部SCC的最小费用】

    Intelligence System Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  3. 将bat批处理命令文件固定到任务栏

    将bat批处理命令文件固定到任务栏第一种方法:使用链接工具http://www.xstui.com/read/3451.在任务栏点击右键,移动到工具栏,勾选链接工具2.你会在通知栏左侧看到链接字样,将 ...

  4. 如果笔记本的 WIN7 运行很卡,请尝试运行这些批处理

    如果笔记本的 WIN7 运行很卡,请尝试运行这些批处理 WIN7是不是很卡?关掉下列服务吧 @echo off rem AppXSvc 为部署应用商店应用程序提供基础结构支持 rem BITS 微软的 ...

  5. [NOI.AC#35]string 缩点+拓扑排序

    链接 因为有交换相邻字母,因此给你字符串就相当于给你了这个字符串的所有排列 把等价的串映射到整数范围,再根据 \(m\) 种魔法连边,缩点后在 DAG 上DP即可 无耻地用了int128 #inclu ...

  6. Spring源码分析专题 —— 阅读指引

    阅读源码的意义 更深入理解框架原理,印象更深刻 学习优秀的编程风格.编程技巧.设计思想 解决实际问题,如修复框架中的bug,或是参考框架源码,结合实际业务需求编写一个独有的框架 阅读源码的方法 首先是 ...

  7. js上传文件(图片)的格式和大小限制

    如果你想快速解决这个问题,看本文就够了.查了好多资料,终于解决了,太耗时间了,本文留给给后来者,希望你们工作的更轻松 本文保存为.html文件用浏览器打开即可测试功能 <form id=&quo ...

  8. 41.关于Intellij IDEA菜单项中Compile、Make和Build的区别

    转自:https://www.cnblogs.com/ini_always/archive/2011/10/23/2221985.html Compile.Make和Build的区别   针对Java ...

  9. 25.Spring @Transactional工作原理

    转自:http://www.importnew.com/12300.html 本文将深入研究Spring的事务管理.主要介绍@Transactional在底层是如何工作的.之后的文章将介绍: prop ...

  10. Eclipse导出Library

         在工作中遇到开发SDK,记录下导出Library的过程. 1.导出   选中项目>属性>Android  配置Is library例如以下图: 选中项目>导出>JAR ...