变换CALayer锚点实现模拟时钟的动画
变换锚点得需要一点理论知识,看下图就能明白:).
开始实现模拟时钟效果:
//
// 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(0, 20, 300, 300)];
showView.layer.borderWidth = 1.f;
showView.layer.cornerRadius = 150.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(0.f, 0.f);
// 设置layer的frame值(在showView正中间摆放)
layer.frame = CGRectMake(showView.middleX, showView.middleY, 1, 150);
// 添加进showView中
[showView.layer addSublayer:layer];
// 定时器
_timer = [[GCDTimer alloc] initInQueue:[GCDQueue mainQueue]];
[_timer event:^{
static int i = 1;
// 每秒增加的角度
layer.transform = \
CATransform3DMakeRotation(DEGREES__TO__RADIANS((360/60.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(0, 0, 200, 30)];
_timeLabel.textAlignment = NSTextAlignmentCenter;
_timeLabel.font = [UIFont fontWithName:@"HelveticaNeue-Thin" size:29.f];
_timeLabel.textColor = [UIColor cyanColor];
_timeLabel.center = self.view.center;
_timeLabel.y += 190;
[self.view addSubview:_timeLabel];
// 显示参考用的view
UIView *showView = [[UIView alloc] initWithFrame:CGRectMake(0, 20, 300, 300)];
showView.layer.borderWidth = 1.f;
showView.layer.cornerRadius = 150.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(0.f, 0.f);
// 设置layer的frame值(在showView正中间摆放)
secondLayer.frame = CGRectMake(showView.middleX, showView.middleY, 1, 140);
// 添加进showView中
[showView.layer addSublayer:secondLayer];
// 新建分钟Layer
// ----------------------------------------------------- //
CALayer *minuteLayer = [CALayer layer];
minuteLayer.backgroundColor = [UIColor greenColor].CGColor;
// 重置锚点
minuteLayer.anchorPoint = CGPointMake(0.f, 0.f);
// 设置layer的frame值(在showView正中间摆放)
minuteLayer.frame = CGRectMake(showView.middleX, showView.middleY, 1, 120);
// 添加进showView中
[showView.layer addSublayer:minuteLayer];
// 新建时钟Layer
// ----------------------------------------------------- //
CALayer *hourLayer = [CALayer layer];
hourLayer.backgroundColor = [UIColor blueColor].CGColor;
// 重置锚点
hourLayer.anchorPoint = CGPointMake(0.f, 0.f);
// 设置layer的frame值(在showView正中间摆放)
hourLayer.frame = CGRectMake(showView.middleX, showView.middleY, 1, 100);
// 添加进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[2] intValue];
float min = [timeArray[1] intValue] + sec / 60.f;
float hour = [timeArray[0] intValue] + min / 60.f;
secondLayer.transform = \
CATransform3DMakeRotation(DEGREES__TO__RADIANS(360/60.f)*sec + \
DEGREES__TO__RADIANS(180), \
0.0, 0.0, 1.0);
minuteLayer.transform = \
CATransform3DMakeRotation(DEGREES__TO__RADIANS(360/60.f)*min + \
DEGREES__TO__RADIANS(180), \
0.0, 0.0, 1.0);
hourLayer.transform = \
CATransform3DMakeRotation(DEGREES__TO__RADIANS(360/24.f)*hour + \
DEGREES__TO__RADIANS(360), \
0.0, 0.0, 1.0);
_timeLabel.text = [NSString stringWithFormat:@"%02d:%02d:%02d",
[timeArray[0] intValue],
[timeArray[1] intValue],
[timeArray[2] intValue]];
} timeInterval:NSEC_PER_SEC];
[_timer start];
}
@end
RootViewController.m