- 論壇徽章:
- 0
|
轉載自 吃唐僧肉的小悟空http://www.cnblogs.com/hukezhu/
今天使用CALayer的"定位點(錨點)"實現了一個時鐘動畫,其實就是一個小的時鐘,只是實現了功能,沒有做出絢麗的效果.使用UIView實現的,其實只是單純的使用layer也可以實現.主要用到了 Quartz2D畫圖\ 事件處理\核心動畫方面的知識.
代碼不是很多,直接附上源碼,注釋比較詳細,在源碼后面再進行解釋其中的一些知識點和注意點.
下圖為應用截圖,使用gif,沒有制作好,見諒哈.[此處圖片有一點小問題,時間顯示正常,指針處有點問題,代碼中修改過來了
1.gif (331.77 KB, 下載次數: 70)
下載附件
2015-06-16 09:42 上傳
下圖為模擬器與電腦時間對比圖,和正常時間一樣.
2.png (102.55 KB, 下載次數: 70)
下載附件
2015-06-16 09:42 上傳
下面附上源代碼:
viewController.m- //
- 2 // ViewController.m
- 3 // 01-時鐘動畫time
- 4 //
- 5 // Created by hukezhu on 15/6/12.
- 6 // Copyright (c) 2015年 hukezhu. All rights reserved.
- 7 //
- 8
- 9 #import "ViewController.h"
- 10
- 11 @interface ViewController ()
- 12 //秒針view
- 13 @property(nonatomic,strong)UIView *secondView;
- 14 //分針view
- 15 @property(nonatomic,strong)UIView *minView;
- 16 //時針view
- 17 @property(nonatomic,strong)UIView *hourView;
- 18 @end
- 19
- 20 @implementation ViewController
- 21
- 22 - (void)viewDidLoad {
- 23 [super viewDidLoad];
- 24 //設置背景顏色
- 25 self.view.backgroundColor = [UIColor greenColor];
- 26
- 27 //創(chuàng)建一個表盤view
- 28 UIView *clockView = [[UIView alloc]init];
- 29 //設置位置
- 30 clockView.center = self.view.center;
- 31 //設置大小
- 32 clockView.layer.bounds = CGRectMake(0, 0, 214, 214);
- 33
- 34 //設置顯示內容
- 35 clockView.layer.contents = (__bridge id)([UIImage imageNamed:@"clock1"].CGImage);
- 36 //設置圓角半徑
- 37 clockView.layer.cornerRadius = 107;
- 38 //設置裁剪
- 39 clockView.layer.masksToBounds = YES;
- 40 //將clockView添加到控制器view中
- 41 [self.view addSubview:clockView];
- 42
- 43
- 44
- 45
- 46 //創(chuàng)建一個秒針view
- 47 UIView *secondView = [[UIView alloc]init];
- 48 secondView.center = clockView.center;
- 49 secondView.layer.bounds = CGRectMake(0, 0, 2, 90);
- 50 secondView.layer.backgroundColor = [UIColor redColor].CGColor;
- 51 secondView.layer.anchorPoint = CGPointMake(0.5, 1);
- 52
- 53 self.secondView = secondView;
- 54 [self.view addSubview:secondView];
- 55
- 56
- 57
- 58 //創(chuàng)建一個分針view
- 59 UIView *minView = [[UIView alloc]init];
- 60 minView.center = clockView.center;
- 61 minView.layer.bounds = CGRectMake(0, 0, 4, 70);
- 62 minView.layer.backgroundColor = [UIColor blueColor].CGColor;
- 63 minView.layer.anchorPoint = CGPointMake(0.5, 1);
- 64
- 65 self.minView = minView;
- 66 [self.view addSubview:minView];
- 67
- 68
- 69
- 70 //創(chuàng)建一個時針view
- 71 UIView *hourView = [[UIView alloc]init];
- 72 hourView.center = clockView.center;
- 73 hourView.layer.bounds = CGRectMake(0, 0, 6, 50);
- 74 hourView.layer.backgroundColor = [UIColor blackColor].CGColor;
- 75 hourView.layer.anchorPoint = CGPointMake(0.5, 1);
- 76
- 77 self.hourView = hourView;
- 78 [self.view addSubview:hourView];
- 79
- 80
- 81 // 開啟一個計時器控件
- 82 //NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(move) userInfo:nil repeats:YES];
- 83 //創(chuàng)建一個對象
- 84 CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(move)];
- 85 //啟動這個link
- 86 [link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
- 87 }
- 88
- 89
- 90 - (void)move{
- 91
- 92
- 93 //1.計算對應的弧度
- 94 CGFloat angle = M_PI * 2 / 60.0;
- 95 CGFloat angleMin = M_PI * 2 / 60.0;
- 96 CGFloat angleHour = M_PI * 2 / 12.0 ;
- 97
- 98 //2.獲取當前事件
- 99 NSDate *date = [NSDate date];
- 100
- 101 //創(chuàng)建一個日歷牌對象(NSCalender),通過這個對象才能獲取NSDate中的日期時間的每一部分
- 102 NSCalendar *calender = [NSCalendar currentCalendar];
- 103
- 104 //告訴日歷牌對象,需要獲取哪些部分的值
- 105
- 106 //取得當前的秒
- 107 NSInteger secs = [calender component:NSCalendarUnitSecond fromDate:date];
- 108 //取得當前的分
- 109 NSInteger mins = [calender component:NSCalendarUnitMinute fromDate:date];
- 110 //取得當前的時
- 111 NSInteger hours = [calender component:NSCalendarUnitHour fromDate:date];
- 112
- 113
- 114 //NSLog(@"%zd,%zd,%zd",hours,mins,secs);//測試用
- 115
- 116
- 117 //計算本次旋轉應該旋轉到的弧度數
- 118 angle = secs *angle;
- 119 angleMin = mins *angleMin + angle/60.0;
- 120 angleHour = hours *angleHour + angleMin/12.0 ;
- 121
- 122 //讓時分秒針旋轉
- 123 self.secondView.transform = CGAffineTransformMakeRotation(angle);
- 124 self.minView.transform = CGAffineTransformMakeRotation(angleMin);
- 125 self.hourView.transform = CGAffineTransformMakeRotation(angleHour);
- 126
- 127 }
- 128
- 129 @end
復制代碼 當然,這里面的表盤使用的時圖片,我們也可以自己畫出來,但是此處有圖片資源,就直接使用了.(注意需要剪切圖片為圓形,當然,有方形的表盤,但是此處是圓形表盤,所以將圖片切割成圓形).
注意:可以使用NSTimer創(chuàng)建一個定時器,但是通過 NSTimer 實現的動畫可能造成卡頓、不連貫的情況(NSTimer 不準確),此處使用CADisplayLink.
主要思路就是:
設置view的背景
創(chuàng)建一個表示表盤的view,設置表盤view的大小和位置,在contents屬性中設置圖片,根據圓角半徑的知識,使用masksToBounds進行剪切,將這個view加到控制器的view中
分別創(chuàng)建一個秒針\分針\時針的view,分別設置大小和位置,設置顏色,等屬性,分別將view加入到控制器的view中.
創(chuàng)建一個CADisplayLink對象,(CADisplayLink能提供一個周期性調用賦值給它的selector的機制,很像定時器NSTimer)
實現上述CADisplayLink對象中添加的move方法
在move方法中,計算所轉的弧度,通過日歷牌對象(NSCalender),獲取NSDate中的日期時間的每一部分
進行旋轉,完畢!
獲取當前系統中的時間的某一部分的方法- //2.獲取當前事件
- 2 NSDate *date = [NSDate date];
- 3
- 4 //創(chuàng)建一個日歷牌對象(NSCalender),通過這個對象才能獲取NSDate中的日期時間的每一部分
- 5 NSCalendar *calender = [NSCalendar currentCalendar];
- 6
- 7 //告訴日歷牌對象,需要獲取哪些部分的值
- 8
- 9 //取得當前的秒
- 10 NSInteger secs = [calender component:NSCalendarUnitSecond fromDate:date];
- 11 //取得當前的分
- 12 NSInteger mins = [calender component:NSCalendarUnitMinute fromDate:date];
- 13 //取得當前的時
- 14 NSInteger hours = [calender component:NSCalendarUnitHour fromDate:date];
- 15
- 16
- 17 //NSLog(@"%zd,%zd,%zd",hours,mins,secs);//測試用
復制代碼 知識點:
注意: 在使用 Quartz2D 繪圖的時候, 對繪圖上下文的旋轉是對坐標系的旋轉, 通過 UI 控件的 transform 對控件做旋轉是按照 Center 來旋轉的。
注意: 控件的 center 屬性, 其實就是對應的 CALayer的 postion。所以控件的 center并不是永遠表示控件的中心點。
ALayer有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之所以能顯示在屏幕上,完全是因為它內部的一個圖層
在創(chuàng)建UIView對象時,UIView內部會自動創(chuàng)建一個圖層(即CALayer對象),通過UIView的layer屬性可以訪問這個層
1 @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的使用區(qū)別:
UIView : 接受和處理系統事件、觸摸事件。
CALayer : 顯示內容 |
|