好了,書接上文。上文地址:juejin.im/post/597962…
被自己的任性感動哭了,哈哈~瞭解了CALayer的一些基本屬性之後,我們開始~擼管~擼起袖子敲程式碼了。
非典型技術宅又突發奇想,把這份程式碼用Objective-C和Swift都敲了一遍。文後面給了兩個版本的原始碼下載地址。
1. 建立CALayer
position
:預設情況下相當於UIView的centercontents
:CALayer的內容。可以設定為圖片,但是需要橋接。橋接不需要自己額外設定,編譯後編譯器會自動提示,讓Xcode自動幫我們橋接就可以啦。- 就像新增子檢視一樣,別忘了把自己建立的Layer新增到view.layer上面。
- (void)viewDidLoad {
[super viewDidLoad];
CALayer *dialLayer= [[CALayer alloc] init];
dialLayer.bounds = CGRectMake(0, 0, 150, 150);
dialLayer.position = self.view.center;
dialLayer.contents = (__bridge id _Nullable)([UIImage imageNamed:@"clock"].CGImage);
[self.view.layer addSublayer:dialLayer];
}複製程式碼
2. 設定時分秒針
以秒針為例。時針、分針都是一樣的。
// 設定秒針
UIView *secondHandView = [[UIView alloc]init];
secondHandView.backgroundColor = [UIColor redColor];
secondHandView.bounds = CGRectMake(0, 0, 1, 60);
secondHandView.center = self.view.center;
// 修改錨點
secondHandView.layer.anchorPoint = CGPointMake(0.5, 1);
[self.view addSubview:secondHandView];
self.secondHandView = secondHandView;複製程式碼
錨點是個神馬東東?
錨點是神馬吶?打個比方,我們耍雙截棍的時候,雙截棍其實都是圍繞我們們握拳的地方轉來轉去的,?其實就是雙截棍的錨點。
再打個比方,我們在一張A4紙上面釘一個?。然後旋轉A4紙,那顆圖釘的位置就是A4紙的錨點。
所以錨點肯定是個座標點嘍~有X、Y組成。錨點的數值範圍就是0~1。0表示在最左邊或者最上邊,1表示在最右邊或者最下邊。有點模糊是不?再來張圖就更清楚了:
我們們剛才繪製的秒針實際就是一個寬1,長60的一個View。我們們要讓它旋轉起來的時候圍繞著一個點轉,就要把那個點用圖釘釘上。這個圖釘的位置就是錨點,就是我們在程式碼中設定的(0.5,1).
3. 建立CADisplayLink
我們一開始想到的辦法就是用定時器,每一秒鐘重新整理一次秒針。但是使用了定時器之後,有一個問題。發現秒針比電腦上的稍微慢一點。是因為重新整理頻率和電腦不一樣。
- 解決方法就是使用CADisplayLink來重新整理時鐘。
// 建立CADisplayLink
CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(clockRunning)];
// 將建立的CADisplayLink加入到主執行緒中
[link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];複製程式碼
3.1 CADisplayLink和NSTimer的區別
- NSTimer佔用系統資源較多
- NSTimer使用完後,一定要銷燬,把它設定成nil。
- CADisplayLink本來就在程式中,每秒進行60次。
- 核心動畫的時候,最好使用CADisplayLink
3.2 獲取時間及時區
- 在
clockRunning
這個方法中,我們要設定時區,獲取日曆、當前時間。
在和時間打交道的時候,請千萬別忘記了時區。全球有那麼多國家,不要只想著自己哈。
//獲取本地時區
NSTimeZone *tZone = [NSTimeZone localTimeZone];
// 獲取日曆
NSCalendar *calendar = [NSCalendar currentCalendar];
//獲取系統當前時間
NSDate *currentDate = [NSDate date];
//設定日曆的時區
[calendar setTimeZone:tZone];
//取出當前的時分秒
NSDateComponents *currentTime = [calendar components:NSCalendarUnitSecond|NSCalendarUnitMinute|NSCalendarUnitHour|NSCalendarUnitTimeZone fromDate:currentDate];複製程式碼
3.3 根據當前時間計算時分秒針弧度
根據當前時間計算時分秒針弧度,然後讓自己設定的View進行形變。
因為我們們這個方法是通過CADisplayLink來呼叫的,也就是說一分鐘會被呼叫60次。因此每秒我們們的秒針都會旋轉一次。
CGFloat angle = (M_PI * 2 / 60) * currentTime.second;
self.secondHandView.transform = CGAffineTransformMakeRotation(angle);
CGFloat minuteAngle = (M_PI * 2 / 60) * currentTime.minute;
self.minuteHandView.transform = CGAffineTransformMakeRotation(minuteAngle);
CGFloat hourAngle = (M_PI * 2 / 12) * currentTime.hour;
self.hourHandView.transform = CGAffineTransformMakeRotation(hourAngle);複製程式碼
4. 成稿
完成效果:
OC和Swift的下載地址如下:
git.oschina.net/atypical/cl…
動畫這個系列大概會分享五篇文章,但是也有可能因為自己偷懶或者其他緣故改變一下。Hoho~
----------華麗分割線,iOS動畫系列全集連結------------------------------------------------
第一篇:iOS動畫系列之一:通過實戰學習CALayer和透視的原理。做一個帶時分秒指標的時鐘動畫(上)
第二篇:iOS動畫系列之二:通過實戰學習CALayer和透視的原理。做一個帶時分秒指標的時鐘動畫。包含了OC和Swift兩種原始碼(下)
第三篇:iOS動畫系列之三:Core Animation。介紹了Core Animation的常用屬性和方法。
第四篇:CABasic Animation。iOS動畫系列之四:基礎動畫之平移篇
第五篇:CABasic Animation。iOS動畫系列之五:基礎動畫之縮放篇&旋轉篇
第六篇:iOS動畫系列之六:利用CABasic Animation完成帶動畫特效的登入介面
第七篇:iOS動畫系列之七:實現類似Twitter的啟動動畫
第八篇:iOS動畫系列之八:使用CAShapeLayer繪畫動態流量圖
第九篇:iOS動畫系列之九:實現點讚的動畫及播放起伏指示器
第十篇:實戰系列:繪製過山車場景