变换CALayer锚点实现模拟时钟的动画

变换锚点得需要一点理论知识,看下图就能明白:).

https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/CoreAnimation_guide/CoreAnimationBasics/CoreAnimationBasics.html#//apple_ref/doc/uid/TP40004514-CH2-SW15

开始实现模拟时钟效果:

//
// RootViewController.m
//
// Copyright (c) 2014年 Y.X. All rights reserved.
// #import "RootViewController.h"
#import "YXGCD.h" @interface RootViewController () @property (nonatomic, strong) GCDTimer *timer; @end // 将角度转换为弧度
#define DEGREES__TO__RADIANS(d) ((d) * M_PI / 180.f) @implementation RootViewController - (void)viewDidLoad
{
[super viewDidLoad]; // 显示参考用的view
UIView *showView = [[UIView alloc] initWithFrame:CGRectMake(, , , )];
showView.layer.borderWidth = .f;
showView.layer.cornerRadius = .f;
showView.layer.borderColor = [UIColor redColor].CGColor;
showView.center = self.view.center;
[self.view addSubview:showView]; // 新建layer
CALayer *layer = [CALayer layer];
layer.backgroundColor = [UIColor blackColor].CGColor; // 重置锚点
layer.anchorPoint = CGPointMake(.f, .f); // 设置layer的frame值(在showView正中间摆放)
layer.frame = CGRectMake(showView.middleX, showView.middleY, , ); // 添加进showView中
[showView.layer addSublayer:layer]; // 定时器
_timer = [[GCDTimer alloc] initInQueue:[GCDQueue mainQueue]];
[_timer event:^{
static int i = ; // 每秒增加的角度
layer.transform = \
CATransform3DMakeRotation(DEGREES__TO__RADIANS((/.f) * i++), 0.0, 0.0, 1.0);
} timeInterval:NSEC_PER_SEC];
[_timer start];
} @end

重要的代码:

以下是最终效果:

完整代码:

//
// RootViewController.m
//
// Copyright (c) 2014年 Y.X. All rights reserved.
// #import "RootViewController.h"
#import "YXGCD.h" static NSDateFormatter* _DMLogDateFormatter = nil; @interface RootViewController () @property (nonatomic, strong) GCDTimer *timer;
@property (nonatomic, strong) UILabel *timeLabel; @end // 将角度转换为弧度
#define DEGREES__TO__RADIANS(d) ((d) * M_PI / 180.f) @implementation RootViewController - (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor blackColor]; // 日期格式
_DMLogDateFormatter = [[NSDateFormatter alloc] init];
[_DMLogDateFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]];
[_DMLogDateFormatter setDateFormat:@"HH:mm:ss"]; // 显示label
_timeLabel = [[UILabel alloc] initWithFrame:CGRectMake(, , , )];
_timeLabel.textAlignment = NSTextAlignmentCenter;
_timeLabel.font = [UIFont fontWithName:@"HelveticaNeue-Thin" size:.f];
_timeLabel.textColor = [UIColor cyanColor];
_timeLabel.center = self.view.center;
_timeLabel.y += ;
[self.view addSubview:_timeLabel]; // 显示参考用的view
UIView *showView = [[UIView alloc] initWithFrame:CGRectMake(, , , )];
showView.layer.borderWidth = .f;
showView.layer.cornerRadius = .f;
showView.layer.borderColor = [UIColor redColor].CGColor;
showView.center = self.view.center;
[self.view addSubview:showView]; // 新建秒钟Layer
// ----------------------------------------------------- //
CALayer *secondLayer = [CALayer layer];
secondLayer.backgroundColor = [UIColor whiteColor].CGColor; // 重置锚点
secondLayer.anchorPoint = CGPointMake(.f, .f); // 设置layer的frame值(在showView正中间摆放)
secondLayer.frame = CGRectMake(showView.middleX, showView.middleY, , ); // 添加进showView中
[showView.layer addSublayer:secondLayer]; // 新建分钟Layer
// ----------------------------------------------------- //
CALayer *minuteLayer = [CALayer layer];
minuteLayer.backgroundColor = [UIColor greenColor].CGColor; // 重置锚点
minuteLayer.anchorPoint = CGPointMake(.f, .f); // 设置layer的frame值(在showView正中间摆放)
minuteLayer.frame = CGRectMake(showView.middleX, showView.middleY, , ); // 添加进showView中
[showView.layer addSublayer:minuteLayer]; // 新建时钟Layer
// ----------------------------------------------------- //
CALayer *hourLayer = [CALayer layer];
hourLayer.backgroundColor = [UIColor blueColor].CGColor; // 重置锚点
hourLayer.anchorPoint = CGPointMake(.f, .f); // 设置layer的frame值(在showView正中间摆放)
hourLayer.frame = CGRectMake(showView.middleX, showView.middleY, , ); // 添加进showView中
[showView.layer addSublayer:hourLayer]; // 定时器
_timer = [[GCDTimer alloc] initInQueue:[GCDQueue mainQueue]];
[_timer event:^{ NSString *timerNow = [_DMLogDateFormatter stringFromDate:[NSDate date]];
NSArray *timeArray = [timerNow componentsSeparatedByString:@":"]; // 获取到时间
float sec = [timeArray[] intValue];
float min = [timeArray[] intValue] + sec / .f;
float hour = [timeArray[] intValue] + min / .f; secondLayer.transform = \
CATransform3DMakeRotation(DEGREES__TO__RADIANS(/.f)*sec + \
DEGREES__TO__RADIANS(), \
0.0, 0.0, 1.0); minuteLayer.transform = \
CATransform3DMakeRotation(DEGREES__TO__RADIANS(/.f)*min + \
DEGREES__TO__RADIANS(), \
0.0, 0.0, 1.0); hourLayer.transform = \
CATransform3DMakeRotation(DEGREES__TO__RADIANS(/.f)*hour + \
DEGREES__TO__RADIANS(), \
0.0, 0.0, 1.0); _timeLabel.text = [NSString stringWithFormat:@"%02d:%02d:%02d",
[timeArray[] intValue],
[timeArray[] intValue],
[timeArray[] intValue]]; } timeInterval:NSEC_PER_SEC];
[_timer start];
} @end

RootViewController.m

变换CALayer锚点实现模拟时钟的动画的更多相关文章

  1. 【CSS3】纯CSS代码实现模拟时钟,+js对时功能。

    使用CSS3纯代码来实现模拟时钟,及指针动画功能. 在这里主要使用到css3一些基本元素: border-radius:圆角边框,画圆形:表盘 Transform:变换,旋转,扭曲:刻度盘,指针形状 ...

  2. 模拟时钟(AnalogClock)和数字时钟(DigitalClock)

    Demo2\clock_demo\src\main\res\layout\activity_main.xml <LinearLayout xmlns:android="http://s ...

  3. 一个模拟时钟的时间选择器 ClockPicker

    最近开发的一个模拟时钟的时间选择器 ClockPicker,用于 Bootstrap,或者单独作为一个 jQuery 插件. 源代码托管在 GitHub 上: ClockPicker 最近项目中需要用 ...

  4. android脚步---数字时钟和模拟时钟

    时钟UI组件是两个非常简单的组件,分为Digitalclock  和Analogclock, main.xml文件,书中程序有问题,加了两个组件,一个Button和一个<Chronometer ...

  5. Java多线程之sleep方法阻塞线程-模拟时钟

    package org.study2.javabase.ThreadsDemo.status; import java.text.SimpleDateFormat; import java.util. ...

  6. css模拟时钟

    css模拟时钟 思路: 画时钟数字(x,y)坐标 x = x0 + r*cos(deg) y = y0 + r*sin(deg) 知识点: 创建元素: createElement 添加元素: appe ...

  7. 模拟时钟(AnalogClock)

    模拟时钟(AnalogClock) 显示一个带时钟和分针的表面 会随着时间的推移变化 常用属性: android:dial 可以为表面提供一个自定义的图片 下面我们直接看代码: 1.Activity ...

  8. Windows下编程--模拟时钟的实现

    windows下编程--模拟时钟的实现: 主要可以分为几个步骤: (1)   编写按键事件处理(启动和停止时钟) (2)   编写时钟事件处理,调用显示时钟函数 (3)   编写显示时钟函数,要调用显 ...

  9. VC++SDK编程——模拟时钟

    #include <Windows.h> #include <tchar.h> #include <math.h> typedef struct Time { in ...

随机推荐

  1. oauth2.0的授权流程详解

    授权模式 1)oauth2.0 提供了四种授权模式,开发者可以根据自己的业务情况自由选择. 授权码授权模式(Authorization Code Grant) 隐式授权模式(简化模式)(Implici ...

  2. js中in关键字的用法

    1. 在For...In 声明用于对数组或者对象的属性进行循环/迭代操作. 例子:var a = new Array; for(x in a){ console.log(x); } 2. 判断对象是否 ...

  3. 04 Thread的方法(源代码) 和 线程的状态

      1 .Thread中重要的属性 publicclass Thread implements Runnable { //继承自Runnable接口private char name[]; // 以c ...

  4. [Mysql 查询语句]——查询字段

    查询所有字段     select  *  from  表名; 可以用 * 号代表所有字段 select * from vendors; +---------+----------------+--- ...

  5. Angular2 不明真相第一个Demo例子

    如果不是去年换工作接触到AngularJS,估计是不会花时间去学习这个框架的,毕竟是前端的框架,不是自己熟悉的领域.但是为了混得下去,去年就学习了AngularJS的一些用法,当时还整理了一些积累 & ...

  6. php 析构函数,构造函数

    php 析构函数,构造函数   <?php /** * 测试使用的PHP操作类 * Date: 2017/7/13 * Time: 14:22 */class Test{ /** 姓名 */ p ...

  7. Thinking in java(1):对象导论

    纯粹的面向对象程序设计的几个特性:1. 万物皆对象2. 程序是对象的合集,他通过发消息告诉彼此要做什么3. 每个对象都有自己的由其他对象所构成的存储4. 每个对象都有其类型5. 某一特定类型的所有对象 ...

  8. nodejs学习笔记四(模块化、在npm上发布自己的模块)

    模块化:      1.系统模块:  http.querystring.url      2.自定义模块      3.包管理器   [系统模块]   Assert      断言:肯定确定会出现的情 ...

  9. JAVA字符编码测试

    几点注意: 1,ASCII码和ISO-8859-1都是单字节编码,ASCII码能表示128个字符,ISO-8859-1总共能表示256个字符.都不能表示中文,如果中文字符或其它不在IOS-8859码值 ...

  10. 最近在研究asp.net mvc

    看了很多大牛写的博客,依然对mvc云里雾里. 有一点是毋庸置疑的C应该是一座桥梁建立在model和view之间. 在ASP.NET MVC中,控制器通常是继承System.Web.Mvc.Contro ...