ios开发-UI进阶-核心动画-时钟动画小案例
2015-06-12 20:29
405 查看
[注意]转载时请注明出处博客园-吃唐僧肉的小悟空http://www.cnblogs.com/hukezhu/
今天使用CALayer的"定位点(锚点)"实现了一个时钟动画,其实就是一个小的时钟,只是实现了功能,没有做出绚丽的效果.使用UIView实现的,其实只是单纯的使用layer也可以实现.主要用到了 Quartz2D画图\ 事件处理\核心动画方面的知识.
代码不是很多,直接附上源码,注释比较详细,在源码后面再进行解释其中的一些知识点和注意点.
下图为应用截图,使用gif,没有制作好,见谅哈.[此处图片有一点小问题,时间显示正常,指针处有点问题,代码中修改过来了]
//2.获取当前事件 NSDate *date = [NSDate date]; //创建一个日历牌对象(NSCalender),通过这个对象才能获取NSDate中的日期时间的每一部分 NSCalendar *calender = [NSCalendar currentCalendar]; //告诉日历牌对象,需要获取哪些部分的值 //取得当前的秒 NSInteger secs = [calender component:NSCalendarUnitSecond fromDate:date]; //取得当前的分 NSInteger mins = [calender component:NSCalendarUnitMinute fromDate:date]; //取得当前的时 NSInteger hours = [calender component:NSCalendarUnitHour fromDate:date]; //NSLog(@"%zd,%zd,%zd",hours,mins,secs);//测试用
获取系统中的时间的某一部分的方法
知识点:
注意: 在使用 Quartz2D 绘图的时候, 对绘图上下文的旋转是对坐标系的旋转, 通过 UI 控件的 transform 对控件做旋转是按照 Center 来旋转的。
注意: 控件的 center 属性, 其实就是对应的 CALayer的 postion。所以控件的 center并不是永远表示控件的中心点。
CALayer有2个非常重要的属性:position和anchorPoint
position:@property CGPoint position;
用来设置CALayer在父层中的位置
以父层的左上角为原点(0, 0)
anchorPoint:
@property CGPoint anchorPoint;
称为“定位点”、“锚点”
决定着CALayer的position属性所指的是哪个点
以自己的左上角为原点(0, 0)
它的x、y取值范围都是0~1,默认值为(0.5, 0.5)
CALayer:
UIView之所以能显示在屏幕上,完全是因为它内部的一个图层
在创建UIView对象时,UIView内部会自动创建一个图层(即CALayer对象),通过UIView的layer属性可以访问这个层
@property(nonatomic,readonly,retain) CALayer *layer;
当UIView需要显示到屏幕上时,会调用drawRect:方法进行绘图,并且会将所有内容绘制在自己的图层上,绘图完毕后,系统会将图层拷贝到屏幕上,于是就完成 了UIView的显示.
CALayer的一些属性
//宽度和高度 @property CGRect bounds; //位置(默认指中点,具体由anchorPoint决定) @property CGPoint position; //锚点(x,y的范围都是0-1),决定了position的含义 @property CGPoint anchorPoint; //背景颜色(CGColorRef类型) @property CGColorRef backgroundColor; //形变属性 @property CATransform3D transform; //边框颜色(CGColorRef类型) @property CGColorRef borderColor; //边框宽度 @property CGFloat borderWidth; //圆角半径 @property CGFloat cornerRadius; //内容(比如设置为图片CGImageRef) @property(retain) id contents;
UIView和CALayer的使用区别:
UIView : 接受和处理系统事件、触摸事件。
CALayer : 显示内容
界面上有显示时间的label:(主要是一个定时器的功能,1秒刷新一次,显示在label上,实时动态的更新时间)
源码代码:
// // ViewController.m // 01-时钟动画time // // Created by hukezhu on 15/6/12. // Copyright (c) 2015年 hukezhu. All rights reserved. // #import "ViewController.h" @interface ViewController () //秒针view @property(nonatomic,strong)UIView *secondView; //分针view @property(nonatomic,strong)UIView *minView; //时针view @property(nonatomic,strong)UIView *hourView; //定时器 @property(nonatomic,strong)NSTimer *timer; //显示时间的label @property(nonatomic,strong)UILabel *timeLabel; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; //设置背景颜色 self.view.backgroundColor = [UIColor greenColor]; //创建一个表盘view UIView *clockView = [[UIView alloc]init]; //设置位置 clockView.center = self.view.center; //设置大小 clockView.layer.bounds = CGRectMake(0, 0, 214, 214); //设置显示内容 clockView.layer.contents = (__bridge id)([UIImage imageNamed:@"clock1"].CGImage); //设置圆角半径 clockView.layer.cornerRadius = 107; //设置裁剪 clockView.layer.masksToBounds = YES; //将clockView添加到控制器view中 [self.view addSubview:clockView]; //创建一个显示时间的label UILabel *label = [[UILabel alloc]init]; //设置位置 label.center = CGPointMake(clockView.center.x, clockView.center.y + 130); //设置大小(这样设置不合理,代码很烂,只是单纯的为了实现这个小功能,也没有做自动布局) label.frame = CGRectMake(clockView.center.x-60, clockView.center.y + 150, 100, 44); //设置背景颜色 label.backgroundColor = [UIColor whiteColor]; //设置字体颜色 label.textColor = [UIColor redColor]; //设置字体居中 label.textAlignment = NSTextAlignmentCenter; //设置字体大小 label.font = [UIFont systemFontOfSize:20]; self.timeLabel = label; [self.view addSubview:label]; //创建一个秒针view UIView *secondView = [[UIView alloc]init]; secondView.center = clockView.center; secondView.layer.bounds = CGRectMake(0, 0, 2, 90); secondView.layer.backgroundColor = [UIColor redColor].CGColor; secondView.layer.anchorPoint = CGPointMake(0.5, 1); self.secondView = secondView; [self.view addSubview:secondView]; //创建一个分针view UIView *minView = [[UIView alloc]init]; minView.center = clockView.center; minView.layer.bounds = CGRectMake(0, 0, 4, 70); minView.layer.backgroundColor = [UIColor blueColor].CGColor; minView.layer.anchorPoint = CGPointMake(0.5, 1); self.minView = minView; [self.view addSubview:minView]; //创建一个时针view UIView *hourView = [[UIView alloc]init]; hourView.center = clockView.center; hourView.layer.bounds = CGRectMake(0, 0, 6, 50); hourView.layer.backgroundColor = [UIColor blackColor].CGColor; hourView.layer.anchorPoint = CGPointMake(0.5, 1); self.hourView = hourView; [self.view addSubview:hourView]; // 开启一个计时器控件 //NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(move) userInfo:nil repeats:YES]; //创建一个对象 CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(move)]; //启动这个link [link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode]; _timer = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(timeRun) userInfo:nil repeats:YES]; } - (void)timeRun{ NSDateFormatter *fmt = [[NSDateFormatter alloc] init]; [fmt setDateFormat:@" HH:mm:ss"]; NSString *time = [fmt stringFromDate:[NSDate date]]; [self.timeLabel setText:time]; } - (void)move{ //1.计算对应的弧度 CGFloat angle = M_PI * 2 / 60.0; CGFloat angleMin = M_PI * 2 / 60.0; CGFloat angleHour = M_PI * 2 / 12.0 ; //2.获取当前事件 NSDate *date = [NSDate date]; //创建一个日历牌对象(NSCalender),通过这个对象才能获取NSDate中的日期时间的每一部分 NSCalendar *calender = [NSCalendar currentCalendar]; //告诉日历牌对象,需要获取哪些部分的值 //取得当前的秒 NSInteger secs = [calender component:NSCalendarUnitSecond fromDate:date]; //取得当前的分 NSInteger mins = [calender component:NSCalendarUnitMinute fromDate:date]; //取得当前的时 NSInteger hours = [calender component:NSCalendarUnitHour fromDate:date]; //NSLog(@"%zd,%zd,%zd",hours,mins,secs);//测试用 //计算本次旋转应该旋转到的弧度数 angle = secs *angle; angleMin = mins *angleMin + angle/60.0; angleHour = hours *angleHour + angleMin/12.0 ; //让时分秒针旋转 self.secondView.transform = CGAffineTransformMakeRotation(angle); self.minView.transform = CGAffineTransformMakeRotation(angleMin); self.hourView.transform = CGAffineTransformMakeRotation(angleHour); } @end
这段代码不是很规范,有许多需要优化的地方,只是单纯的实现了这个功能,请勿喷~~~~~~~~
相关文章推荐
- WordSequence API
- poj 2299 Ultra-QuickSort
- UITabBarController用法详解 - iOS - UI基础知识总结15
- Android异步处理三:Handler+Looper+MessageQueue深入详解
- Quick Reference:php5 Xdebug 生成Profiles
- Android异步处理二:使用AsyncTask异步更新UI界面
- Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面
- iOS开发UI篇—0408控制器View的生命周期方法
- TopCoder SRM 661 Div2 Problem 500 - BridgeBuildingDiv2 (枚举 + 状态压缩)
- UI之各种控件的属性及使用方法说明(一)
- 可编程硬件Arduino初探(2)-神奇的鸡腿multiwii
- [译]可编程硬件Arduino初探(4)-MultiWii之config.h
- SpannableString与SpannableStringBuilder
- wordpress文本编辑器百度UEditor中无法正常显示换行
- iOS开发UI篇—0408控制器的三种创建方式
- EasyUI Tree
- iOS UICollectionView的使用(用storyboard和xib创建)
- SQL SERVER完整、差异和事务日志备份及还原(脚本和GUI实现) [原创]
- DevExpress.Build.v14.2
- LeetCode Implement Stack using Queues