变换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. JAVA list对象排序加去重问题

    对象类实现继承Comparable接口重写compareTo方法实现排序功能,重写equals方法实现去重功能(根据ID去重)public class TestAbilityAnalyze imple ...

  2. c++ 同步阻塞队列

    参考:<C++11深入应用> 用同步阻塞队列解决生产者消费者问题. 生产者消费者问题: 有一个生产者在生产产品,这些产品将提供给若干个消费者去消费,为了使生产者和消费者能并发执行,在两者之 ...

  3. JAVA的静态代理与动态代理比较--转载

    扩展:http://www.ibm.com/developerworks/cn/java/j-lo-proxy1/JAVA的静态代理与动态代理比较 一.概念 代理模式是常用的Java 设计模式,它的特 ...

  4. CentOS7手动修改系统时间

    CentOS7 永久修改系统时间 安装在虚拟机上的CentOS7的时间分为系统时间和硬件时间.二者都修改,重启系统(init 6 )才会永久生效.修改步骤如下 查看当前系统时间 date    修改当 ...

  5. IOS项目之弹出动画二

    在IOS项目之弹出动画一中只是实现也功能,并没有体现面向对象的思想 ,今天就试着把它封装了一下,弹出视图的内容可以根据自定义,此处只是用UIDatePicker来演示 我把它传到了GitHub上    ...

  6. ThinkPHP出现项目目录不可写,目录无法自动生成

    问题描述:维护一个老项目,用的TP2.1,down完代码,配好环境,访问的时候出现“项目目录不可写,目录无法自动生成!请使用项目生成器或者手动生成项目目录~”: 问题原因:在linux 服务器上,th ...

  7. XAMPP环境的搭建

    XAMPP是一个强大的集成软件包(什么是集成软件包?就是多个软件打包一起安装了,比如office办公软件包括了word.Excel.PPT) XAMPP包括了Apache,MySQL,PHP,Perl ...

  8. HTML页面格式

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  9. [C#]LockBits使用笔记

    昨天想基于一张图片做个手机锁屏来着,原图如下:主要是嫌白底太丑了,一开始是想画图工具直接油漆桶伺候,然而一浇上去就发现问题了,变成了这样:看来得手工处理一下把底色统一了,原图分辨率挺高的,SetPix ...

  10. 关于JAVA是值传递还是引用传递的问题

    1.概念 值传递:方法调用时,实际传入的是它的副本,在方法中对值的修改,不影响调用者的值. 引用传递:方法调用时,实际传入的是参数的实际内存地址,调用者和调用方法所操作的参数都指向同一内存地址,所以方 ...