iOS學習——核心動畫

来源:https://www.cnblogs.com/mukekeheart/archive/2018/07/27/9375549.html
-Advertisement-
Play Games

iOS學習——核心動畫 1、什麼是核心動畫 Core Animation(核心動畫)是一組功能強大、效果華麗的動畫API,無論在iOS系統或者在你開發的App中,都有大量應用。核心動畫所在的位置如下圖所示,可以看到,核心動畫位於UIKit的下一層,相比UIView動畫,它可以實現更複雜的動畫效果。 ...


iOS學習——核心動畫

1、什麼是核心動畫

  Core Animation(核心動畫)是一組功能強大、效果華麗的動畫API,無論在iOS系統或者在你開發的App中,都有大量應用。核心動畫所在的位置如下圖所示,可以看到,核心動畫位於UIKit的下一層,相比UIView動畫,它可以實現更複雜的動畫效果。

  核心動畫作用在CALayer(Core animation layer)上,CALayer的概念、作用以及layer與UIView的區別在上一篇文章中有詳細的描述,想瞭解的朋友可以參見 iOS學習——核心動畫之Layer基礎,我們可以將UIView看成是一種特殊的CALayer(可以響應事件)。實際上,每一個view都有其對應的layer,這個layer是root layer:

@property (nonatomic, readonly, strong)  CALayer  *layer;

  給view加上動畫,本質上是對其layer進行操作,layer包含了各種支持動畫的屬性,動畫則包含了屬性變化的值、變化的速度、變化的時間等等,兩者結合產生動畫的過程。核心動畫和UIView動畫的對比:UIView動畫可以看成是對核心動畫的封裝,和UIView動畫不同的是,通過核心動畫改變layer的狀態(比如position),動畫執行完畢後實際上是沒有改變的(錶面上看起來已改變)。總體來說核心動畫的優點有:

1)性能強大,使用硬體加速,可以同時向多個圖層添加不同的動畫效果

2)介面易用,只需要少量的代碼就可以實現複雜的動畫效果。

3)運行在後臺線程中,在動畫過程中可以響應交互事件(UIView動畫預設動畫過程中不響應交互事件)。

4)CoreAnimation是跨平臺的,既可以支持IOS,也支持MAC OS 

2、核心動畫類的層次結構 

  • CAAnimation是所有動畫對象的父類,實現CAMediaTiming協議,負責控制動畫的時間、速度和時間曲線等等,是一個抽象類,不能直接使用。
  • CAPropertyAnimation :是CAAnimation的子類,它支持動畫地顯示圖層的keyPath,一般不直接使用。
  • CASpringAnimation是iOS9.0之後新增的類,它實現彈簧效果的動畫,是CABasicAnimation的子類。
  • CAAnimationGroup使用Group可以將多個動畫合併一起加入到層中,Group中所有動畫併發執行,可以方便地實現需要多種類型動畫的場景。
  • CATransition 主要用於轉場動畫從一個場景以動畫的形式過渡到另一個場景,比如Nav的預設Push視圖的效果就是通過CATransition的kCATransitionPush類型來實現。

  綜上,核心動畫類中可以直接使用的類有:

  CABasicAnimation

  CAKeyframeAnimation

  CATransition

  CAAnimationGroup

  CASpringAnimation

3、 簡單使用CoreAnimation的步驟

使用CoreAnimation做動畫的時候,遵循四步就好

  1. 創建CAAnmation子對象,因為CAAnmation是抽象類,所以一般要使用自具體子類,就是上面說的五類
  2. 設置CAAnmation的屬性,不同的動畫類別屬性參數不一樣的
  3. 調用CALayer的addAnimation:forKey:將CAAnimation對象添加到CALayer上,就能執行動畫
  4. 調用CALayer的removeAnimationForKey方法可以停止CALayer中的動畫

4、CABasicAnimation和CAKeyframeAnimation

CABasicAnimation和CAKeyframeAnimation都是CAPropertyAnimation的子類,這兩類動畫有著相似的地方,但是也有不同的地方。

    • 這兩類動畫有相似的地方,就是這兩類動畫都是通過描繪路徑來形成動畫
    • CABasicAnimation通過設定起始點,終點,時間,動畫會沿著你這設定點進行移動
    • CAKeyFrameAnimation則可以設置路徑為更多的點構成的路徑,動畫會沿著我們設置的多個點進行移動。
    • CABasicAnimation可以看成是只有兩個點的特殊的CAKeyFrameAnimation動畫

  這其中主要的參數有: 

屬性解釋
duration 動畫的持續時間
repeatCount 動畫持續次數,最大次數用MAXFLOAT
repeatDuration 設置動畫的時間,在該時間內動畫一直執行,不計次數
beginTime 指定動畫開始的時間。從開始延遲幾秒的話,設置為CACurrentMediaTime() + 秒數 的方式
timingFunction 設置動畫的速度變化
fillMode 動畫在開始和結束時的動作,預設值是 kCAFillModeRemoved
autoreverses 動畫結束時是否執行逆動畫
fromValue 所改變屬性的起始值(CABasicAnimation獨有)
toValue 所改變屬性的結束時的值(CABasicAnimation獨有)
byValue 所改變屬性相同起始值的改變數(CABasicAnimation獨有)

values

 關鍵幀數組對象,裡面每一個元素即為一個關鍵幀,動畫會在對應的時間段內,依次執行數組中每一個關鍵幀的動畫(CAKeyframeAnimation獨有)

keyTimes

 上面values設定了路徑上的關鍵點,本參數則設定關鍵點之間的路徑段上所需的時間,所以keyTimes的個數應該比values的個數小1(CAKeyframeAnimation獨有)

timingFunctions

 同上keyTimes的含義,及設置每一小段路徑上的動畫的變化速率(CAKeyframeAnimation獨有)
 path  可以直接設置動畫路徑(CAKeyframeAnimation獨有)

KeyPath常用的屬性:

KeyPath值說明使用形式- swift 3.0
transform.scale 比例縮放 0.8
transform.scale.x 縮放寬的比例 0.8
transform.scale.y 縮放高的比例 0.8
transform.rotation.x 圍繞x軸旋轉 2 * M_PI
transform.rotation.y 圍繞y軸旋轉 2 * M_PI
transform.rotation.z 圍繞z軸旋轉 2 * M_PI
backgroundColor 背景顏色的變化 UIColor.red.cgColor
bounds 大小縮放,中心不變 NSValue(cgRect: CGRect(x: 800, y: 500, width: 90, height: 30))
position 位置(中心點的改變) NSValue(cgPoint: CGPoint(x: 40, y: 240))
contents 內容,比如UIImageView的圖片 UIImage(named: "to")?.cgImage
opacity 透明度 0.4
contentsRect.size.width 橫向拉伸縮放 0.6
contentsRect.size.height 縱向拉伸縮放 0.5

timingFunction主要有五種類別:

  • kCAMediaTimingFunctionLinear,在整個動畫時間內動畫都是以一個相同的速度來改變,也就是勻速運動。一個線性的計時函數,同樣也是CAAnimation的timingFunction屬性為空時候的預設函數。線性步調對於那些立即加速並且保持勻速到達終點的場景會有意義(例如射出槍膛的子彈)。
  • kCAMediaTimingFunctionEaseIn:動畫開始時會較慢,之後動畫會加速,一個慢慢加速然後突然停止的方法。對於之前提到的自由落體的例子來說很適合,或者比如對準一個目標的導彈的發射。
  • kCAMediaTimingFunctionEaseOut:動畫在開始時會較快,之後動畫速度減慢,它以一個全速開始,然後慢慢減速停止。它有一個削弱的效果,應用的場景比如一扇門慢慢地關上,而不是砰地一聲。
  • kCAMediaTimingFunctionEaseInEaseOut:動畫在開始和結束時速度較慢,中間時間段內速度較快。創建了一個慢慢加速然後再慢慢減速的過程。這是現實世界大多數物體移動的方式,也是大多數動畫來說最好的選擇。如果只可以用一種緩衝函數的話,那就必須是它了。那麼你會疑惑為什麼這不是預設的選擇,實際上當使用UIView的動畫方法時,他的確是預設的,但當創建CAAnimation的時候,就需要手動設置它了。
  • kCAMediaTimingFunctionDefault:它和kCAMediaTimingFunctionEaseInEaseOut很類似,但是加速和減速的過程都稍微有些慢。它和kCAMediaTimingFunctionEaseInEaseOut的區別很難察覺,可能是蘋果覺得它對於隱式動畫來說更適合(然後對UIKit就改變了想法,而是使用kCAMediaTimingFunctionEaseInEaseOut作為預設效果),雖然它的名字說是預設的,但還是要記住當創建顯式的CAAnimation它並不是預設選項(換句話說,預設的圖層行為動畫用kCAMediaTimingFunctionDefault作為它們的計時方法)。

fillMode主要有四種類型:

  • kCAFillModeForwards :動畫開始之後layer的狀態將保持在動畫的最後一幀,而removedOnCompletion的預設屬性值是 YES,所以為了使動畫結束之後layer保持結束狀態,應將removedOnCompletion設置為NO
  • kCAFillModeBackwards :將會立即執行動畫的第一幀,不論是否設置了 beginTime屬性。觀察發現,設置該值,剛開始視圖不見,還不知道應用在哪裡
  • kCAFillModeBoth:該值是 kCAFillModeForwards 和 kCAFillModeBackwards的組合狀態
  • kCAFillModeRemoved:動畫將在設置的 beginTime 開始執行(如沒有設置beginTime屬性,則動畫立即執行),動畫執行完成後將會layer的改變恢複原狀。
/* CABasicAnimation應用
    心跳效果
    思路:就是讓一張圖片做一個放大縮放小的動畫.
*/
    
//代碼實現:
     
- (void) viewDidLoad {
    CABasicAnimation *anim =[CABasicAnimation  animation];
    //設置縮放屬性
    anim.keyPath = @"transform.scale";
    //縮放到一半
    anim.toValue = @0.5;
    //設置動畫執行的次數
    anim.repeatCount = MAXFLOAT;
    //設置動畫執行的時長
    anim.duration = 0.25;
    //設置動畫自動反轉(怎麼去, 怎麼回)
    anim.autoreverses = YES;
    //添加動畫
    [self.heartView.layer addAnimation:anim forKey:nil];
}

 

/* CAKeyframeAnimation的應用
    圖片抖動
    思路:其實就是做一個左右旋轉的動畫.先讓它往左邊旋轉-5,再往右邊旋轉5度,再從5度旋轉到-5度. 就會有左右搖擺的效果了.
*/
        
//圖標抖動代碼實現
- (void)values{

    //創建一個幀動畫
    CAKeyframeAnimation *anim = [CAKeyframeAnimation animation];    
    //設置屬性
    anim.keyPath = @"transform.rotation";    
    //設置屬性值.
    anim.values = @[@(angle2Rad(-5)),@(angle2Rad(5)),@(angle2Rad(-5))];
    //設置執行的次數
    anim.repeatCount = MAXFLOAT;
    
    anim.duration = 0.25;
    
    //添加動畫
    [self.iconV.layer addAnimation:anim forKey:nil];

}

 

//我們還可以直接設置關鍵幀CAKeyframeAnimation動畫的路徑 path屬性

-(void)touchesBegan:(nonnull NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event{
    
    //創建一個幀動畫
    CAKeyframeAnimation *anim = [CAKeyframeAnimation animation];
    
    //設置屬性
    anim.keyPath = @"position";
    //直接設置動畫的路徑path是畫弧
    UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(50, 50, 300, 400)];   
    anim.path = path.CGPath;

    //設置執行的次數
    anim.repeatCount = MAXFLOAT;
   //設置是否反轉
    anim.autoreverses = YES;
    
    anim.duration = 1;
    
    //添加動畫
    [self.iconV.layer addAnimation:anim forKey:nil];
}

5、 CATransition轉場動畫

  iOS中實現轉場動畫有兩種方式,一種是通過我們今天學的CATransition轉場動畫進行,還有一種則是通過UIView的動畫進行。CAKeyframeAnimation的重要屬性:

  type:過渡動畫的類型

//轉場類型,字元串類型參數.系統提供了四中動畫形式:
//kCATransitionFade//淡出效果//kCATransitionMoveIn//新視圖移動到舊視圖上//kCATransitionPush//新視圖推出舊視圖//kCATransitionReveal//移開舊視圖顯示新視圖//另外,除了系統給的這幾種動畫效果,我們還可以使用系統私有的動畫效果:
//@"cube",//立方體翻轉效果
//@"oglFlip",//翻轉效果
//@"suckEffect",//收縮效果,動畫方向不可控
//@"rippleEffect",//水滴波紋效果,動畫方向不可控
//@"pageCurl",//向上翻頁效果
//@"pageUnCurl",//向下翻頁效果
//@"cameralIrisHollowOpen",//攝像頭打開效果,動畫方向不可控
//@"cameraIrisHollowClose",//攝像頭關閉效果,動畫方向不可控
subtype:設置轉場方向
//轉場方向,系統一共提供四個方向:
//kCATransitionFromRight//從右開始
//kCATransitionFromLeft//從左開始
//kCATransitionFromTop//從上開始
//kCATransitionFromBottom//從下開始

startProgress:開始進度,預設0.0.如果設置0.3,那麼動畫將從動畫的0.3的部分開始
endProgress:結束進度,預設1.0.如果設置0.6,那麼動畫將從動畫的0.6部分以後就會結束

-(void)touchesBegan:(nonnull NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event{
    //UIView執行轉場動畫
    [UIView transitionWithView:self.imageV duration:1 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{

        _i++;
        if (_i > 3) {
            _i = 1;
        }
        NSString *imageName = [NSString stringWithFormat:@"%d",_i];
        self.imageV.image = [UIImage imageNamed:imageName];

    } completion:nil];    
    
}

 

-(void)touchesBegan:(nonnull NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event{

    //轉場代碼必須得要和轉場動畫在同一個方法當中.
    //創建動畫
    CATransition *anim = [CATransition animation];
    //設置轉場類型
    anim.type = @"cube";
    //設置轉場的方向
    anim.subtype = kCATransitionFromTop;
    //設置動畫的開始點.
    anim.startProgress = 0.2;
    //設置動畫的結束點.
    anim.endProgress = 0.8;

    [self.imageV.layer addAnimation:anim forKey:nil];
    
    //轉場代碼必須得要和轉場動畫在同一個方法當中.
    _i++;
    if (_i > 3) {
        _i = 1;
    }
    NSString *imageName = [NSString stringWithFormat:@"%d",_i];
    self.imageV.image = [UIImage imageNamed:imageName]; 
}

6、CASpringAnimation

  CASpringAnimation是iOS9新加入動畫類型,是CABasicAnimation的子類,用於實現彈簧動畫。CASpringAnimation的重要屬性

  • mass:質量(影響彈簧的慣性,質量越大,彈簧慣性越大,運動的幅度越大)
  • stiffness:彈性繫數(彈性繫數越大,彈簧的運動越快)
  • damping:阻尼繫數(阻尼繫數越大,彈簧的停止越快)
  • initialVelocity:初始速率(彈簧動畫的初始速度大小,彈簧運動的初始方向與初始速率的正負一致,若初始速率為0,表示忽略該屬性)
  • settlingDuration:結算時間(根據動畫參數估算彈簧開始運動到停止的時間,動畫設置的時間最好根據此時間來設置
- (void)springAni {
    CASpringAnimation * ani = [CASpringAnimation animationWithKeyPath:@"bounds"];
    ani.mass = 10.0; //質量,影響圖層運動時的彈簧慣性,質量越大,彈簧拉伸和壓縮的幅度越大
    ani.stiffness = 5000; //剛度繫數(勁度繫數/彈性繫數),剛度繫數越大,形變產生的力就越大,運動越快
    ani.damping = 100.0;//阻尼繫數,阻止彈簧伸縮的繫數,阻尼繫數越大,停止越快
    ani.initialVelocity = 5.f;//初始速率,動畫視圖的初始速度大小;速率為正數時,速度方向與運動方向一致,速率為負數時,速度方向與運動方向相反
    ani.duration = ani.settlingDuration;
    ani.toValue = [NSValue valueWithCGRect:self.centerShow.bounds];
    ani.removedOnCompletion = NO;
    ani.fillMode = kCAFillModeForwards;
    ani.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    [self.cartCenter.layer addAnimation:ani forKey:@"boundsAni"];
}

7、CAAnimationGroup

  使用Group可以將多個動畫合併一起加入到層中,Group中所有動畫併發執行,可以方便地實現需要多種類型動畫的場景。

-(void)touchesBegan:(nonnull NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event{
  
    CAAnimationGroup *group = [CAAnimationGroup animation];
    
    //縮放
    CABasicAnimation *scaleAnim = [CABasicAnimation animation];
    //設置屬性
    scaleAnim.keyPath = @"transform.scale";
    scaleAnim.toValue = @0.5;

    //平移
    CABasicAnimation *Anim = [CABasicAnimation animation];
    //設置屬性
    Anim.keyPath = @"position.y";
    Anim.toValue = @(400);

    //將上面兩個動畫添加到動畫組
    group.animations = @[scaleAnim,Anim];
    
    //設置動畫的屬性,一定要在動畫組上設置
    group.removedOnCompletion = NO;
    group.fillMode  = kCAFillModeForwards;
    //添加動畫
    [self.redView.layer addAnimation:group forKey:nil];
    
}

 

參考資料:

iOS動畫篇:核心動畫

iOS動畫詳解(學習動畫看這一篇就夠了)

CALayer與核心動畫

iOS動畫-從不會到熟練應用

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1.背景 iOS開發這幾年, UI佈局工具從frame到Masonry到SnapKit, sb和xib的AutoLayout也用過, 但是代碼版本的AutoLayout倒是沒用過, 最近一年, 頻頻發現一些三方UI組件佈局的bug, 作為三方組件不可能去依賴另一個三方的kayout倉庫, 所以只能通 ...
  • 創建Execl、寫入Execl數據、導入U盤 發送帶附件的郵件 ...
  • 2018年6月5日蘋果`WWDC`開發者大會之後,蘋果已經永久暫停`4006701855`中文開發者電話支持。 現在需要電話支持的話,只能被動要求,讓蘋果客服打電話給你。那怎麼獲得蘋果開發者咨詢服務呢? 請參照博文~ ...
  • 有時候後臺json數據返回的欄位含有“id”,也有可能是有時候為了減少代碼的冗餘,兩頁面之間只是數據模型個別屬性的區別,所以這時候最好是用到模型屬性的替換,用新的屬性替換返回的json數據的欄位。這裡主要總結了兩種使用方法,都是在項目已經集成別人封裝好的解析json數據的庫的基礎上。 以常見Yima ...
  • Instruments 使用Xcode自帶的 Instruments 檢測工具對App進行檢測,它可以檢測程式在運行時的記憶體泄漏。這是與靜態記憶體檢測的最大不同。 Open Instruments 打開Instruments的兩種方式: 第一種: 打開Xcode,點擊 Product -> profi ...
  • "RetrofitUtils" "GitHub地址,幫忙給個Star" 項目介紹 Retrofit+Okhttp輔助類的簡單封裝,vesion 1.0.X 實現了Get,Post Form、Post Json 三種形式的網路請求,後續版本會實現文件上傳下載and各類raw的請求方式。 功能 1. G ...
  • (1).場景一:外部滑動方向跟內部滑動方向不一致,比如外部左右滑動,內部上下滑動 ViewPager+Fragment配合使用,會有滑動衝突,但是ViewPager內部處理了這種滑動衝突 如果採用的不是ViewPager而是ScrollView就必須手動處理滑動事件 上下滑動時,需要上一級view把 ...
  • 雲之聲離線Jar包和so文件下載地址 下載地址 Android SoundPool語音播放類 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...