变换CALayer锚点实现模拟时钟的动画
变换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