UIView和CALayer是相互依赖的关系。UIView依赖与calayer提供的内容,CALayer依赖uivew提供的容器来显示绘制的内容。归根到底CALayer是这一切的基础,如果没有CALayer,UIView自身也不会存在,UIView是一个特殊的CALayer实现,添加了响应事件的能力。下面使用 CALayer 实现了时钟的功能。
界面效果如下:
代码如下:
//
// ViewController.m
// 时钟
// Created by pkxing on 14/12/8.
// Copyright (c) 2014年 梦醒. All rights reserved.
//
#define angle2radian(x) ((x)/ 180.0 * M_PI)
#define CZSecondAngle (2 * M_PI / 60) // 秒针每一秒走6度
#define CZMinusAngle (2 * M_PI / 3600) // 分针每一秒走的度数
#define CZHourAngle (2 * M_PI / (3600 * 120)) // 时针每一秒走的度数
// 每小时时钟转多少度
#define CZPerHourA 30
#import "ViewController.h"
@interface ViewController ()
@property(nonatomic,weak) CALayer *secondLayer;
@property(nonatomic,weak) CALayer *minusLayer;
@property(nonatomic,weak) CALayer *hourLayer;
@property(nonatomic,weak) CALayer *clockLayer;
@end
@implementation ViewController
/**
* 懒加载时钟图层
*/
- (CALayer *)clockLayer {
if (_clockLayer == nil) {
CGFloat width = 200.0f;
CALayer *clockLayer = [CALayer layer];
clockLayer.position = self.view.center;
clockLayer.backgroundColor = [UIColor whiteColor].CGColor;
clockLayer.bounds = CGRectMake(0, 0, width, width);
clockLayer.contents = (id)([UIImage imageNamed:@"钟表"].CGImage);
[self.view.layer addSublayer:clockLayer];
_clockLayer = clockLayer;
}
return _clockLayer;
}
- (void)viewDidLoad {
[super viewDidLoad];
NSDate *date = [NSDate date];
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *components = [calendar components:NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond fromDate:date];
NSInteger second = components.second;
NSInteger hour = components.hour;
NSInteger minus = components.minute;
CGFloat width = self.clockLayer.bounds.size.width;
// 秒针
self.secondLayer = [self layerWithPosition:CGPointMake(width * 0.5, width * 0.5) bounds:CGRectMake(0, 0, 3, 80) backgroundColor:[UIColor redColor]];
//分针
self.minusLayer = [self layerWithPosition:CGPointMake(width * 0.5, width * 0.5) bounds:CGRectMake(0, 0, 3, 70) backgroundColor:[UIColor blueColor]];
//时针
self.hourLayer = [self layerWithPosition:CGPointMake(width * 0.5, width * 0.5) bounds:CGRectMake(0, 0, 3, 50) backgroundColor:[UIColor blackColor]];
// 根据当前时间旋转图层的角度
self.secondLayer.transform = CATransform3DMakeRotation(CZSecondAngle * second, 0, 0, 1);
self.minusLayer.transform = CATransform3DMakeRotation(CZSecondAngle * minus, 0, 0, 1);
self.hourLayer.transform = CATransform3DMakeRotation(angle2radian(CZPerHourA * (minus / 60.0 + hour)), 0, 0, 1);
[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateTime) userInfo:nil repeats:YES];
}
/**
* 创建一个图层对象
*
* @param position 图层位置
* @param bounds 图层大小
* @param backgroundColor 图层演示
*
* @return 创建好的图层
*/
- (CALayer *)layerWithPosition:(CGPoint)position bounds:(CGRect)bounds backgroundColor:(UIColor *)backgroundColor{
CALayer *layer = [CALayer layer];
layer.position = position;
layer.anchorPoint = CGPointMake(0.5, 1);
layer.bounds = bounds;
layer.backgroundColor = backgroundColor.CGColor;
[self.clockLayer addSublayer:layer];
return layer;
}
/**
* 每一秒更新一次时间
*/
- (void)updateTime{
self.secondLayer.transform = CATransform3DRotate(self.secondLayer.transform, CZSecondAngle, 0, 0, 1);
self.minusLayer.transform = CATransform3DRotate(self.minusLayer.transform, CZMinusAngle, 0, 0, 1);
self.hourLayer.transform = CATransform3DRotate(self.hourLayer.transform, CZHourAngle, 0, 0, 1);
}
@end