iOS开发之时钟实现

思路就是利用CALayer的隐式动画来实现。因为UIView的非根层也就是手动创建的layer在其属性发生变化时会默认会产生动画效果,这些属性也叫作可动画属性。比如bounds、backgroundColor、position。

时钟里面表盘就是一个UIView,而三根针就是三个手动创建的layer。

先在storyboard上弄一个UIImageView,设置表盘图片

005304_Z4UQ_1011331.png

然后在viewDidLoad中初始化三根针,并设置定时器,获取当前时间,将当前时间对应的时针分针秒针分别指向对应的角度。

//
//  ViewController.m
//  时钟效果
//
//  Created by Daniel on 16/4/7.
//  Copyright © 2016年 Daniel. All rights reserved.
//

#define kClockWH _clockView.bounds.size.width

//一秒钟秒针转多少度
#define preSecondA 6

//一分钟分针转多少度
#define preMinuteA 6

//一小时时针转多少度
#define preHourA 30

//每分钟时针转多少度
#define preHourMinute 0.5

//每秒钟分针转多少度
#define preMinuteSecond 0.1

#define angle2raditon(a) ((a) / 180.0 * M_PI)

#import "ViewController.h"

@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *clockView;

/** 秒针 */
@property(nonatomic, strong) CALayer *secondL;

/** 分针 */
@property(nonatomic, strong) CALayer *minuteL;

/** 时针 */
@property(nonatomic, strong) CALayer *hourL;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    //添加时针
    [self setUpHourLayer];
    
    //添加分针
    [self setUpMinuteLayer];
   
    //添加秒针
    [self setUpSecondLayer];
    
    //添加定时器
    [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timeChange) userInfo:nil repeats:YES];
    
    //开始运行时就获取时间,这样在启动时就不会有停顿的感觉
    [self timeChange];
    
}

- (void)timeChange {
    
    //获取当前系统时间
    NSCalendar *calendar = [NSCalendar currentCalendar];
    
    NSDateComponents *cmp = [calendar components:NSCalendarUnitSecond | NSCalendarUnitMinute | NSCalendarUnitHour  fromDate:[NSDate date]];
    
    //获取秒
    NSInteger second = cmp.second;
    
    //获取分
    NSInteger minute = cmp.minute;
    
    //获取小时
    NSInteger hour = cmp.hour;
    
    //计算秒针转多少度
    CGFloat secondA = second * preSecondA;
    
    //计算分针转多少度
    CGFloat minuteA = minute * preMinuteA + second * preMinuteSecond;
    
    //计算时针转多少度
    CGFloat hourA = hour * preHourA + minute * preHourMinute;
    
    //旋转秒针
    _secondL.transform = CATransform3DMakeRotation(angle2raditon(secondA), 0, 0, 1);
    
    //旋转分针
    _minuteL.transform = CATransform3DMakeRotation(angle2raditon(minuteA), 0, 0, 1);
    
    //旋转时针
    _hourL.transform = CATransform3DMakeRotation(angle2raditon(hourA), 0, 0, 1);
    
}

#pragma mark - 初始化时针
- (void)setUpHourLayer {
    
    CALayer *hourL = [CALayer layer];
    
    //设置背景色
    hourL.backgroundColor = [UIColor blackColor].CGColor;
    
    //设置锚点
    hourL.anchorPoint = CGPointMake(0.5, 1);
    
    //设置锚点在父控件的位置
    hourL.position = CGPointMake(kClockWH * 0.5, kClockWH * 0.5);
    
    //设置圆角半径
    hourL.cornerRadius = 4;
    
    //设置bounds
    hourL.bounds = CGRectMake(0, 0, 4, kClockWH * 0.5 - 40);
    
    //添加到clockView图层上
    [_clockView.layer addSublayer:hourL];
    
    _hourL = hourL;
    
}


#pragma mark - 初始化分针
- (void)setUpMinuteLayer {
    
    CALayer *minuteL = [CALayer layer];
    
    //设置背景色
    minuteL.backgroundColor = [UIColor blackColor].CGColor;
    
    //设置锚点
    minuteL.anchorPoint = CGPointMake(0.5, 1);
    
    //设置锚点在父控件的位置
    minuteL.position = CGPointMake(kClockWH * 0.5, kClockWH * 0.5);
    
    //设置圆角半径
    minuteL.cornerRadius = 4;
    
    //设置bounds
    minuteL.bounds = CGRectMake(0, 0, 4, kClockWH * 0.5 - 20);
    
    //添加到clockView图层上
    [_clockView.layer addSublayer:minuteL];
    
    _minuteL = minuteL;
    
}

#pragma mark - 初始化秒针
- (void)setUpSecondLayer {
    
    CALayer *secondL = [CALayer layer];
    
    //设置秒针背景色
    secondL.backgroundColor = [UIColor redColor].CGColor;
    
    //设置秒针锚点
    secondL.anchorPoint = CGPointMake(0.5, 1);
    
    //设置秒针锚点在父控件的位置
    secondL.position = CGPointMake(kClockWH * 0.5, kClockWH * 0.5);
    
    
    //设置秒针bounds
    secondL.bounds = CGRectMake(0, 0, 1.5, kClockWH * 0.5 - 20);
    
    //把秒针添加到clockView图层上
    [_clockView.layer addSublayer:secondL];
    
    _secondL = secondL;
    
}


@end


最后的效果图:

005844_Jvhw_1011331.gif 

转载于:https://my.oschina.net/shenhuniurou/blog/654869

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值