您的位置:首页 > 产品设计 > UI/UE

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


这段代码不是很规范,有许多需要优化的地方,只是单纯的实现了这个功能,请勿喷~~~~~~~~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: