主頁 > 移動端開發 > UIView Animation 影片學習總結

UIView Animation 影片學習總結

2022-09-02 09:08:14 移動端開發

目錄
  • 一、前言
  • 二、UIView Animation
    • 2.1 簡單影片
    • 2.2 關鍵幀影片
    • 2.3 View 的轉換
  • 三、CALayer Animation
    • 3.1 基本影片(CABasicAnimation)
    • 3.2 關鍵幀影片(CAKeyframeAnimation)
    • 3.3 影片組(CAAnimationGroup)
    • 3.4 切換影片(CATransition)
  • 四、后記

一、前言

影片一直是 iOS 開發中很重要的一部分,設計良好,效果炫酷的影片往往能對用戶體驗的提升起到很大的作用,在這里將自己學習 iOS 影片的體會記錄下來,希望能對別人有所幫助,

iOS 的影片框架,即 CoreAnimation,本身十分龐大和復雜,這里暫時分兩個部分進行介紹,分別是 UIView 影片CALayer 影片

二、UIView Animation

2.1 簡單影片

對于 UIView 上簡單的影片,iOS 提供了很方便的函式:

animateWithDuration:animations:
  • 第一個引數是影片的持續時間,
  • 第二個引數是一個 block,在 animations block 中對 UIView 的屬性進行調整,設定 UIView 影片結束后最終的效果,iOS 就會自動補充中間幀,形成影片,

可以更改的屬性有:

  • frame
  • bounds
  • center
  • transform
  • alpha
  • backgroundColor
  • contentStretch

這些屬性大都是 View 的基本屬性,下面是一個例子,這個例子中的影片會同時改變 View 的 framebackgroundColoralpha

[UIView animateWithDuration:2.0 animations:^{
    myView.frame = CGRectMake(50, 200, 200, 200);
    myView.backgroundColor = [UIColor blueColor];
    myView.alpha = 0.7;
}];

其中有一個比較特殊的 transform 屬性,它的型別是 CGAffineTransform,即 2D 仿射變換,這是個數學中的概念,用一個三維矩陣來表述 2D 圖形的矢量變換,用 transform 屬性對 View 進行:

  • 旋轉
  • 縮放
  • 其他自定義 2D 變換

iOS 提供了下面的函式可以創建簡單的 2D 變換:

  • CGAffineTransformMakeScale
  • CGAffineTransformMakeRotation
  • CGAffineTransformMakeTranslation

例如下面的代碼會將 View 縮小至原來的 1/4 大小:

[UIView animateWithDuration:2.0 animations:^{
    myView.transform = CGAffineTransformMakeScale(0.5, 0.5);
}];

調節引數

完整版的 animate 函式其實是這樣的:

animateWithDuration:delay:options:animations:completion:

可以通過 delay 引數調節讓影片延遲產生,同時還一個 options 選項可以調節影片進行的方式,可用的 options 可分為兩類:

一、控制程序

例如 UIViewAnimationOptionRepeat 可以讓影片反復進行, UIViewAnimationOptionAllowUserInteraction 可以讓允許用戶對影片進行程序中同 View 進行互動(默認是不允許的)

二、控制速度

影片的進行速度可以用速度曲線來表示(參考這里),提供的選項例如 :

  • UIViewAnimationOptionCurveEaseIn 是先慢后快,
  • UIViewAnimationOptionCurveEaseOut 是先快后慢,

不同的選項直接可以通過“”操作進行合并,同時使用,例如:

UIViewAnimationOptionRepeat | UIViewAnimationOptionAllowUserInteraction

2.2 關鍵幀影片

上面介紹的影片中,我們只能控制開始和結束時的效果,然后由系統補全中間的程序,有些時候我們需要自己設定若干關鍵幀,實作更復雜的影片效果,這時候就需要關鍵幀影片的支持了,下面是一個示例:

[UIView animateKeyframesWithDuration:2.0 delay:0.0 options:UIViewKeyframeAnimationOptionRepeat | UIViewKeyframeAnimationOptionAutoreverse animations:^{

    [UIView addKeyframeWithRelativeStartTime:0.0 relativeDuration:0.5 animations:^{
        self.myView.frame = CGRectMake(10, 50, 100, 100);
    }];

    [UIView addKeyframeWithRelativeStartTime: 0.5 relativeDuration:0.3 animations:^{
        self.myView.frame = CGRectMake(20, 100, 100, 100);
    }];

    [UIView addKeyframeWithRelativeStartTime:0.8 relativeDuration:0.2 animations:^{
        self.myView.transform = CGAffineTransformMakeScale(0.5, 0.5);
    }];
} completion:nil];

這個例子添加了三個關鍵幀,在外面的 animateKeyframesWithDuration 中我們設定了持續時間為 2.0 秒,這是真實意義上的時間,里面的 startTimerelativeDuration 都是相對時間,以第一個為例,startTime 為 0.0,relativeTime 為 0.5,這個影片會直接開始,持續時間為 2.0 X 0.5 = 1.0 秒,下面第二個的開始時間是 0.5,正好承接上一個結束,第三個同理,這樣三個影片就變成連續的影片了,

2.3 View 的轉換

iOS 還提供了兩個函式,用于進行兩個 View 之間通過影片換場:

  • transitionWithView:duration:options:animations:completion:
  • transitionFromView:toView:duration:options:completion:

需要注意的是,換場影片會在這兩個 View 共同的父 View 上進行,在寫影片之前,先要設計好 View 的繼承結構,

同樣,View 之間的轉換也有很多選項可選,例如

  • UIViewAnimationOptionTransitionFlipFromLeft 從左邊翻轉,
  • UIViewAnimationOptionTransitionCrossDissolve 漸變等等,

三、CALayer Animation

在這里插入圖片描述

UIView 的影片簡單易用,但是能實作的效果相對有限,上面介紹的 UIView 的幾種影片方式,實際上是對底層 CALayer 影片的一種封裝,直接使用 CALayer 層的影片方法可以實作更多高級的影片效果,

3.1 基本影片(CABasicAnimation)

在這里插入圖片描述

CABasicAnimation 用于創建一個 CALayer 上的基本影片效果,下面是一個例子:

CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position.x"];
animation.toValue = https://www.cnblogs.com/reyzhang/p/@200;
animation.duration = 0.8;
animation.repeatCount = 5;
animation.beginTime = CACurrentMediaTime() + 0.5;
animation.fillMode = kCAFillModeRemoved;
[self.myView.layer addAnimation:animation forKey:nil];

KeyPath

這里我們使用了 animationWithKeyPath 這個方法來改變 layer 的屬性,可以使用的屬性有很多,具體可以參考這里和這里,其中很多屬性在前面介紹的 UIView 影片部分我們也看到過,進一步驗證了 UIView 的影片方法是對底層 CALayer 的一種封裝,

需要注意的一點是,上面我們使用了 position 屬性, layer 的這個 position 屬性和 View 的 frame 以及 bounds 屬性都不相同,而是和 Layer 的 anchorPoint有關,可以由下面的公式計算得到:

position.x = frame.origin.x + 0.5 * bounds.size.width;  
position.y = frame.origin.y + 0.5 * bounds.size.height;

關于 anchorPointposition 屬性的以及具體計算的原理可以參考這篇文章,

屬性

·CABasicAnimation 的屬性有下面幾個:

  • beginTime
  • duration
  • fromValue
  • toValue
  • byValue
  • repeatCount
  • autoreverses
  • timingFunction

可以看到,其中 beginTimedurationrepeatCount 等屬性和上面在 UIView 中使用到的 durationUIViewAnimationOptionRepeat等選項是相對應的,不過這里的選項能夠提供更多的擴展性,

需要注意的是 fromValuetoValuebyValue 這幾個選項,支持的設定模式有下面幾種:

  • 設定 fromValuetoValue:從 fromValue 變化到 toValue
  • 設定 fromValuebyValue:從 fromValue 變化到 fromValue + byValue
  • 設定 byValuetoValue:從 toValue - byValue 變化到 toValue
  • 設定 fromValue: 從 fromValue 變化到屬性當前值
  • 設定 toValue從屬性當前值變化到 toValue
  • 設定 byValue從屬性當前值變化到屬性當前值 + toValue

看起來挺復雜,其實概括起來基本就是 :如果某個值不設定,就是用這個屬性當前的值

另外,可以看到上面我們使用的:

animation.toValue = https://www.cnblogs.com/reyzhang/p/@200;

而不是直接使用 200,因為 toValue 之類的屬性為 id 型別,或者像這樣使用 @ 符號,或者使用:

animation.toValue = https://www.cnblogs.com/reyzhang/p/[NSNumber numberWithInt:200];

最后一個比較有意思的是 timingFunction 屬性,使用這個屬性可以自定義影片的運動曲線(節奏,pacing),系統提供了五種值可以選擇:

  • kCAMediaTimingFunctionLinear 線性影片
  • kCAMediaTimingFunctionEaseIn 先快后慢
  • kCAMediaTimingFunctionEaseOut 先慢后快
  • kCAMediaTimingFunctionEaseInEaseOut 先慢后快再慢
  • kCAMediaTimingFunctionDefault 默認,也屬于中間比較快

此外,我們還可以使用 [CAMediaTimingFunction functionWithControlPoints] 方法來自定義運動曲線,這個網站提供了一個將引數調節可視化的效果,關于影片時間系統的具體介紹可以參考這篇文章,

3.2 關鍵幀影片(CAKeyframeAnimation)

同 UIView 中的類似,CALayer 層也提供了關鍵幀影片的支持,CAKeyFrameAnimationCABasicAnimation 都繼承自 CAPropertyAnimation,因此它有具有上面提到的那些屬性,此外,CAKeyFrameAnimation 還有特有的幾個屬性,

values 和 keyTimes

使用 valueskeyTimes 可以共同確定一個影片的若干關鍵幀,示例代碼如下:

CAKeyframeAnimation *anima = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation"];//在這里@"transform.rotation"==@"transform.rotation.z"
NSValue *value1 = [NSNumber numberWithFloat:-M_PI/180*4];
NSValue *value2 = [NSNumber numberWithFloat:M_PI/180*4];
NSValue *value3 = [NSNumber numberWithFloat:-M_PI/180*4];

anima.values = @[value1,value2,value3];
// anima.keyTimes = @[@0.0, @0.5, @1.0];
anima.repeatCount = MAXFLOAT;

[_demoView.layer addAnimation:anima forKey:@"shakeAnimation"];

可以看到上面這個影片共有三個關鍵幀,如果沒有指定 keyTimes 則各個關鍵幀會平分整個影片的時間(duration),

path

使用 path 屬性可以設定一個影片的運動路徑,注意 path 只對 CALayer 的 anchorPoint position 屬性起作用另外如果你設定了 path ,那么 values 將被忽略,

CAKeyframeAnimation *anima = [CAKeyframeAnimation animationWithKeyPath:@"position"];
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(SCREEN_WIDTH/2-100, SCREEN_HEIGHT/2-100, 200, 200)];
anima.path = path.CGPath;
anima.duration = 2.0f;
[_demoView.layer addAnimation:anima forKey:@"pathAnimation"];

3.3 影片組(CAAnimationGroup)

組影片可以將一組影片組合在一起,所有影片物件可以同時運行,示例代碼如下:

CAAnimationGroup *group = [[CAAnimationGroup alloc] init];

//1.基礎影片一
CABasicAnimation *animationOne = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
animationOne.toValue = https://www.cnblogs.com/reyzhang/p/@2.0;
animationOne.duration = 1.0;

//2.基礎影片二
CABasicAnimation *animationTwo = [CABasicAnimation animationWithKeyPath:@"position.x"];
animationTwo.toValue = https://www.cnblogs.com/reyzhang/p/@400;
animationTwo.duration = 1.0;

[group setAnimations:@[animationOne, animationTwo]];
[self.myView.layer addAnimation:group forKey:nil];

需要注意的是,一個 group 組內的某個影片的持續時間(duration),如果超過了整個組的影片持續時間,那么多出的影片時間將不會被展示,例如一個 group 的持續時間是 5s,而組內一個影片持續時間為 10s ,那么這個 10s 的影片只會展示前 5s ,

3.4 切換影片(CATransition)

CATransition 可以用于 View 或 ViewController 直接的換場影片:

self.myView.backgroundColor = [UIColor blueColor];
CATransition *trans = [CATransition animation];
trans.duration = 1.0;
trans.type = @"push";
[self.myView.layer addAnimation:trans forKey:nil];

// 這句放在下面也可以
// self.myView.backgroundColor = [UIColor blueColor];

為什么改變顏色放在前后都可以呢?具體的解釋可以參考 SO 上的這個回答,簡單來說就是影片和繪制之間并不沖突,

四、后記

如果本文對你有一點幫助的話,歡迎收藏、點贊,感謝,文中如有不對之處,也歡迎大家在評論區指出,共勉,

本文來自博客園,作者:reyzhang,轉載請注明原文鏈接:https://www.cnblogs.com/reyzhang/p/16645372.html

轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/503440.html

標籤:iOS

上一篇:如何在保護用戶隱私的同時實作精準廣告投放?

下一篇:基于AVFoundation實作視頻錄制的兩種方式

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【從零開始擼一個App】Dagger2

    Dagger2是一個IOC框架,一般用于Android平臺,第一次接觸的朋友,一定會被搞得暈頭轉向。它延續了Java平臺Spring框架代碼碎片化,注解滿天飛的傳統。嘗試將各處代碼片段串聯起來,理清思緒,真不是件容易的事。更不用說還有各版本細微的差別。 與Spring不同的是,Spring是通過反射 ......

    uj5u.com 2020-09-10 06:57:59 more
  • Flutter Weekly Issue 66

    新聞 Flutter 季度調研結果分享 教程 Flutter+FaaS一體化任務編排的思考與設計 詳解Dart中如何通過注解生成代碼 GitHub 用對了嗎?Flutter 團隊分享如何管理大型開源專案 插件 flutter-bubble-tab-indicator A Flutter librar ......

    uj5u.com 2020-09-10 06:58:52 more
  • Proguard 常用規則

    介紹 Proguard 入口,如何查看輸出,如何使用 keep 設定入口以及使用實體,如何配置壓縮,混淆,校驗等規則。

    ......

    uj5u.com 2020-09-10 06:59:00 more
  • Android 開發技術周報 Issue#292

    新聞 Android即將獲得類AirDrop功能:可向附近設備快速分享檔案 谷歌為安卓檔案管理應用引入可安全隱藏資料的Safe Folder功能 Android TV新主界面將顯示電影、電視節目和應用推薦內容 泄露的Android檔案暗示了傳說中的谷歌Pixel 5a與折疊屏新機 谷歌發布Andro ......

    uj5u.com 2020-09-10 07:00:37 more
  • AutoFitTextureView Error inflating class

    報錯: Binary XML file line #0: Binary XML file line #0: Error inflating class xxx.AutoFitTextureView 解決: <com.example.testy2.AutoFitTextureView android: ......

    uj5u.com 2020-09-10 07:00:41 more
  • 根據Uri,Cursor沒有獲取到對應的屬性

    Android: 背景:呼叫攝像頭,拍攝視頻,指定保存的地址,但是回傳的Cursor檔案,只有名稱和大小的屬性,沒有其他諸如時長,連ID屬性都沒有 使用 cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DURATIO ......

    uj5u.com 2020-09-10 07:00:44 more
  • Android連載29-持久化技術

    一、持久化技術 我們平時所使用的APP產生的資料,在記憶體中都是瞬時的,會隨著斷電、關機等丟失資料,因此android系統采用了持久化技術,用于存盤這些“瞬時”資料 持久化技術包括:檔案存盤、SharedPreference存盤以及資料庫存盤,還有更復雜的SD卡記憶體儲。 二、檔案存盤 最基本存盤方式, ......

    uj5u.com 2020-09-10 07:00:47 more
  • Android Camera2Video整合到自己專案里

    背景: Android專案里呼叫攝像頭拍攝視頻,原本使用的 MediaStore.ACTION_VIDEO_CAPTURE, 后來因專案需要,改成了camera2 1.Camera2Video 官方demo有點問題,下載后,不能直接整合到專案 問題1.多次拍攝視頻崩潰 問題2.雙擊record按鈕, ......

    uj5u.com 2020-09-10 07:00:50 more
  • Android 開發技術周報 Issue#293

    新聞 谷歌為Android TV開發者提供多種新功能 Android 11將自動填表功能整合到鍵盤輸入建議中 谷歌宣布Android Auto即將支持更多的導航和數字停車應用 谷歌Pixel 5只有XL版本 搭載驍龍765G且將比Pixel 4更便宜 [圖]Wear OS將迎來重磅更新:應用啟動時間 ......

    uj5u.com 2020-09-10 07:01:38 more
  • 海豚星空掃碼投屏 Android 接收端 SDK 集成 六步驟

    掃碼投屏,開放網路,獨占設備,不需要額外下載軟體,微信掃碼,發現設備。支持標準DLNA協議,支持倍速播放。視頻,音頻,圖片投屏。好點意思。還支持自定義基于 DLNA 擴展的操作動作。好像要收費,沒體驗。 這里簡單記錄一下集成程序。 一 跟目錄的build.gradle添加私有mevan倉庫 mave ......

    uj5u.com 2020-09-10 07:01:43 more
最新发布
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:40:31 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:40:11 more
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:39:36 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:39:13 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:16:23 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:16:15 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:15:46 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:14:53 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:14:08 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:08:34 more