iOS動畫系列之二:帶時分秒指標的時鐘動畫(下)

非典型技術宅發表於2018-12-26

好了,書接上文。上文地址:juejin.im/post/597962…

被自己的任性感動哭了,哈哈~瞭解了CALayer的一些基本屬性之後,我們開始~擼管~擼起袖子敲程式碼了。

非典型技術宅又突發奇想,把這份程式碼用Objective-C和Swift都敲了一遍。文後面給了兩個版本的原始碼下載地址。

1. 建立CALayer

  • position:預設情況下相當於UIView的center
  • contents: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.png
錨點示意圖1.png

錨點示意圖2.png
錨點示意圖2.png

我們們剛才繪製的秒針實際就是一個寬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];複製程式碼
  • 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. 成稿

完成效果:

Paste_Image.png
Paste_Image.png

OC和Swift的下載地址如下:
git.oschina.net/atypical/cl…

iOS實踐:帶時分秒指標的時鐘動畫(OC和Swift兩版)

動畫這個系列大概會分享五篇文章,但是也有可能因為自己偷懶或者其他緣故改變一下。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動畫系列之九:實現點讚的動畫及播放起伏指示器
第十篇:實戰系列:繪製過山車場景

相關文章