iOS動畫:帶時分秒指針的時鐘動畫(上)

通過幾回實驗,發現若是分享的文章能構成系列,效果會很是好。同時本身也能收穫很大,可以整塊整塊的複習,也可以幫助本身更深刻的塊狀學習知識。對本身梳理線條,整理知識體系做用很是大。ios

因此此次仍是打算用這種方式,一塊兒來分享一下iOS中關於動畫的部分。iOS 的動畫渲染簡直是帥的不要不要的,哈哈。其實當初就是由於iOS的動畫,還有iOS的對手勢的處理深深的打動了我,才讓我這樣一個高齡中年老男人開始了iOS這條路。啦啦啦啦~bash

開始我們的第一篇內容。函數

1. 最終實現的效果以及思惟導圖

實現的效果。不當心暴露了寫文章的時間。-_-+++
學習

實現效果
實現效果

實現的步驟思惟導圖:
動畫

思惟導圖.png
思惟導圖.png

2. CALayer

其實今天分享的主角是CALayer。由於全部的動畫都是在CALayer上完成的。ui

  • 在iOS中,看得見摸得着的東西基本上都是UIView,好比一個按鈕、一個文本標籤、一個文本輸入框、一個圖標等等,這些都是UIView
  • 其實UIView之因此能顯示在屏幕上,徹底是由於它內部的一個圖層
  • 在建立UIView對象時,UIView內部會自動建立一個圖層(即CALayer對象),經過UIView的layer屬性能夠訪問這個層
    @property(nonatomic,readonly,retain) CALayer *layer;
  • 當UIView須要顯示到屏幕上時,會調用drawRect:方法進行繪圖,而且會將全部內容繪製在本身的圖層上,繪圖完畢後,系統會將圖層拷貝到屏幕上,因而就完成了UIView的顯示
  • 換句話說,UIView自己不具有顯示的功能,是它內部的層纔有顯示功能

2.1 CALayer的基本屬性

屬性類型 屬性名稱 用途
@property CGFloat borderWidth; 邊寬
@property CGColorRef borderColor; 邊的顏色
@property CGColorRef backgroundColor; 背景顏色
@property float opacity; 透明度
@property CGColorRef shadowColor; 陰影顏色
@property float shadowOpacity; 陰影透明度,設置範圍0~1。
@property CGSize shadowOffset; 陰影的偏移
@property CGFloat shadowRadius; 陰影的模糊度
@property(strong) id contents; 內容。能夠設置爲圖片,可是須要橋接。
@property CGFloat cornerRadius; 圓角
@property CGRect bounds; Layer的大小
@property CGPoint position; 默認狀況下至關於UIView的center
@property CGPoint anchorPoint; position的錨點
@property CATransform3D transform; 用來作形變的,是一個矩陣。能夠理解爲結構體。
@property BOOL masksToBounds; 超過部分進行裁剪
  • 設置陰影的時候,陰影顏色+陰影偏移(或者陰影路徑)+陰影透明度缺一不可。
  • 陰影模糊度若是不設置,默認值就是3.0000。
  • 陰影的路徑:
    • 設置了陰影的路徑,就再也不須要設置陰影的偏移量了。
    • 設置了陰影的路徑以後,也不能再設置masksToBounds。由於超過部分會被裁減。
      以實現下圖爲例:

Paste_Image.png
Paste_Image.png

UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];

    [self.view addSubview:imageView];

//    設置背景顏色。注意UIColor 和 CGColor之間的互換
    imageView.layer.backgroundColor = [UIColor grayColor].CGColor;

//    生成一個path
    UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(-10, -10, imageView.bounds.size.width + 20, imageView.bounds.size.height + 20)];
//    設置陰影path
    imageView.layer.shadowPath = path.CGPath;

//    設置陰影顏色
    imageView.layer.shadowColor = [UIColor lightGrayColor].CGColor;

//    設置陰影透明度
    imageView.layer.shadowOpacity = 0.5;複製代碼

2.2 手動建立一個CALayer

  • 建立CALayer
  • 在設置frame的時候,內部同時設置了position,bounds.size 都會發生改變。
  • 設置position,就和設置UIView的center同樣的。
  • 記得要添加到父CALayer上。
CALayer *layer = [[CALayer alloc] init];

 // ------------------- 設置位置大小 ---------------------
 // 方式一: 直接設置 frame
 // layer.frame = CGRectMake(50, 50, 200, 200);


 // 方式二:
 // 先設置大小
 layer.bounds = CGRectMake(0, 0, 100, 100);
 // 再設置位置(默認狀況下 position 指的是 center。)
 layer.position = CGPointMake(150, 150);
 // ------------------- 設置位置大小 ---------------------

 layer.backgroundColor = [UIColor redColor].CGColor;
 layer.opacity = 0.7;
 [self.view.layer addSublayer:layer];
 }複製代碼

2.3 transform

從這裏開始,我們的座標軸就變成了xyz三個軸向了,由於圖案也會變成立體的了。atom

  • 從 layer 的中心點到 給定的座標點之間連一條線, 而後以這個線爲中心軸, 開始旋轉
    self.myLayer.transform = CATransform3DMakeRotation(M_PI_4, 10, 20, 30);複製代碼

    這段代碼的意思就是說從{0,0,0}這個點,到{10,20,30}這個點,劃一根線。圖形繞着這根線,旋轉M_PI_4度數。spa

2.3.1 修改透視

在真實世界中,當物體遠離咱們的時候,因爲視角的緣由看起來會變小,理論上說遠離咱們的視圖的邊要比靠近視角的邊跟短,但實際上並無發生,而咱們當前的視角是等距離的,也就是在3D變換中任然保持平行,和以前提到的仿射變換相似。code

「爲了作一些修正,咱們須要引入投影變換(又稱做z變換)來對除了旋轉以外的變換矩陣作一些修改,Core Animation並無給咱們提供設置透視變換的函數,所以咱們須要手動修改矩陣值,幸運的是,很簡單:CATransform3D的透視效果經過一個矩陣中一個很簡單的元素來控制:m34。m34用於按比例縮放X和Y的值來計算到底要離視角多遠。」orm

Excerpt From: 鐘聲. 「ios核心動畫高級技巧.」 iBooks.

Paste_Image.png
Paste_Image.png

  • 經過修改transform的m34來達到效果
  • transform能夠當作是一個結構體,因此修改的時候須要經過一箇中間量才能修改。
  • m34的默認值是0,能夠經過設置m34爲-1.0 / d來應用透視效果
  • d表明了想象中視角相機和屏幕之間的距離,以像素爲單位,那應該如何計算這個距離呢?實際上並不須要,大概估算一個就行了。」
  • 「由於視角相機實際上並不存在,因此能夠根據屏幕上的顯示效果自由決定它的防止的位置。一般500-1000就已經很好了」

Excerpt From: 鐘聲. 「ios核心動畫高級技巧.」 iBooks.

struct CATransform3D{  
  CGFloat     m11(x縮放),   m12(y切變),   m13(旋轉),   m14();
  CGFloat     m21(x切變),   m22(y縮放),   m23,        m24;
  CGFloat     m31(旋轉),    m32,         m33,         m34(透視效果,要有旋轉角度才能看出效果);
  CGFloat     m41(x平移),   m42(y平移),   m43(z平移),  m44;
};



 struct CGAffineTransform {
 CGFloat a, b, c, d;
 CGFloat tx, ty;
 };複製代碼
//    定義矩陣
    CATransform3D transform = CATransform3DIdentity;

    transform.m34 = -1.0 / 800;

//    旋轉加透視
    transform = CATransform3DRotate(transform, -M_PI_4, 0, 1, 0);

    imageView.layer.transform = transform;複製代碼

2.3.2 縮放

//方式一:
transform = CATransform3DMakeScale(<#CGFloat sx#>, <#CGFloat sy#>, <#CGFloat sz#>)

//方式二:
transform = CATransform3DScale(imageView.layer.transform, <#CGFloat sx#>, <#CGFloat sy#>, <#CGFloat sz#>)複製代碼

2.4 重要屬性之position和anchorPoint

  • 默認狀況下position至關於UIView 的center
  • position決定了layer在父上的位置。
  • 可是anchorPoint決定了position在自身的位置。
  • anchorPoint的數值只能是0~1。因此是按照百分比計算的。

3. 隱式動畫

  • 當對非Root Layer的部分屬性進行修改時,默認會自動產生一些動畫效果
  • 全部的非Root Layer,也就是手動建立的CALayer對象,都存在着隱式動畫
  • 全部註釋裏面寫着有Animatable,這個屬性就有隱式動畫效果。

Paste_Image.png
Paste_Image.png

3.1 幾個常見的Animatable Properties:

  • bounds:用於設置CALayer的寬度和高度。修改這個屬性會產生縮放動畫
  • backgroundColor:用於設置CALayer的背景色。修改這個屬性會產生背景色的漸變更畫
  • position:用於設置CALayer的位置。修改這個屬性會產平生移動畫

3.2 關閉隱式動畫

  • 能夠經過動畫事務(CATransaction)關閉默認的隱式動畫效果
  • 關閉或者修改隱式動畫的步驟:
    • 開啓動畫事物
    • 關閉動畫效果或者修改動畫事件
    • 設置動畫完成後的動做(能夠不設置)
    • 修改屬性
      • 提交
        //開啓
        [CATransaction begin];
        //關閉動畫
        [CATransaction setDisableActions:YES];
        //修改屬性
        self.myview.layer.position = CGPointMake(10, 10);
        //提交
        [CATransaction commit];複製代碼

寶貝兒們,我錯了。寫到這裏發現已經辣麼長辣麼長了,再寫下去這篇該沒有人看了。

那麼,那麼。。。。就臨時變卦吧,把這篇文章變成上下集吧。哈哈~就這麼愉快的本身打本身的臉了~

因此,證實一個道理。計劃都只是用來計劃的,樹立一個目標,能不能實現再說。哈哈~

相關文章
相關標籤/搜索