事務(隱式動畫)

来源:http://www.cnblogs.com/EchoHG/archive/2017/10/03/7624765.html
-Advertisement-
Play Games

事務 Core Animation基於一個假設,說屏幕上的任何東西都可以(或者可能)做動畫。動畫並不需要你在Core Animation中手動打開,相反需要明確地關閉,否則他會一直存在。 當你改變CALayer的一個可做動畫的屬性,它並不能立刻在屏幕上體現出來。相反,它是從先前的值平滑過渡到新的值。 ...


事務

Core Animation基於一個假設,說屏幕上的任何東西都可以(或者可能)做動畫。動畫並不需要你在Core Animation中手動打開,相反需要明確地關閉,否則他會一直存在。

當你改變CALayer的一個可做動畫的屬性,它並不能立刻在屏幕上體現出來。相反,它是從先前的值平滑過渡到新的值。這一切都是預設的行為,你不需要做額外的操作。

這看起來這太棒了,似乎不太真實,我們來用一個demo解釋一下:首先和第一章“圖層樹”一樣創建一個藍色的方塊,然後添加一個按鈕,隨機改變它的顏色。代碼見清單7.1。點擊按鈕,你會發現圖層的顏色平滑過渡到一個新值,而不是跳變(圖7.1)。

清單7.1 隨機改變圖層顏色

 1 @interface ViewController ()
 2 
 3 @property (nonatomic, weak) IBOutlet UIView *layerView;
 4 @property (nonatomic, weak) IBOutlet CALayer *colorLayer;/*熱心人發現這裡應該改為@property (nonatomic, strong)  CALayer *colorLayer;否則運行結果不正確。
 5 */
 6 @end
 7 
 8 @implementation ViewController
 9 
10 - (void)viewDidLoad
11 {
12     [super viewDidLoad];
13     //create sublayer
14     self.colorLayer = [CALayer layer];
15     self.colorLayer.frame = CGRectMake(50.0f, 50.0f, 100.0f, 100.0f);
16     self.colorLayer.backgroundColor = [UIColor blueColor].CGColor;
17     //add it to our view
18     [self.layerView.layer addSublayer:self.colorLayer];
19 }
20 
21 - (IBAction)changeColor
22 {
23     //randomize the layer background color
24     CGFloat red = arc4random() / (CGFloat)INT_MAX;
25     CGFloat green = arc4random() / (CGFloat)INT_MAX;
26     CGFloat blue = arc4random() / (CGFloat)INT_MAX;
27     self.colorLayer.backgroundColor = [UIColor colorWithRed:red green:green blue:blue alpha:1.0].CGColor;                                                                                       
28 }
29 
30 @end

 

圖7.1 添加一個按鈕來控製圖層顏色

這其實就是所謂的隱式動畫。之所以叫隱式是因為我們並沒有指定任何動畫的類型。我們僅僅改變了一個屬性,然後Core Animation來決定如何並且何時去做動畫。Core Animaiton同樣支持顯式動畫,下章詳細說明。

但當你改變一個屬性,Core Animation是如何判斷動畫類型和持續時間的呢?實際上動畫執行的時間取決於當前事務的設置,動畫類型取決於圖層行為

事務實際上是Core Animation用來包含一系列屬性動畫集合的機制,任何用指定事務去改變可以做動畫的圖層屬性都不會立刻發生變化,而是當事務一旦提交的時候開始用一個動畫過渡到新值。

事務是通過CATransaction類來做管理,這個類的設計有些奇怪,不像你從它的命名預期的那樣去管理一個簡單的事務,而是管理了一疊你不能訪問的事務。CATransaction沒有屬性或者實例方法,並且也不能用+alloc-init方法創建它。但是可以用+begin+commit分別來入棧或者出棧。

任何可以做動畫的圖層屬性都會被添加到棧頂的事務,你可以通過+setAnimationDuration:方法設置當前事務的動畫時間,或者通過+animationDuration方法來獲取值(預設0.25秒)。

Core Animation在每個run loop周期中自動開始一次新的事務(run loop是iOS負責收集用戶輸入,處理定時器或者網路事件並且重新繪製屏幕的東西),即使你不顯式的用[CATransaction begin]開始一次事務,任何在一次run loop迴圈中屬性的改變都會被集中起來,然後做一次0.25秒的動畫。

明白這些之後,我們就可以輕鬆修改變色動畫的時間了。我們當然可以用當前事務的+setAnimationDuration:方法來修改動畫時間,但在這裡我們首先起一個新的事務,於是修改時間就不會有別的副作用。因為修改當前事務的時間可能會導致同一時刻別的動畫(如屏幕旋轉),所以最好還是在調整動畫之前壓入一個新的事務。

修改後的代碼見清單7.2。運行程式,你會發現色塊顏色比之前變得更慢了。

清單7.2 使用CATransaction控制動畫時間

 1 - (IBAction)changeColor
 2 {
 3     //begin a new transaction
 4     [CATransaction begin];
 5     //set the animation duration to 1 second
 6     [CATransaction setAnimationDuration:1.0];
 7     //randomize the layer background color
 8     CGFloat red = arc4random() / (CGFloat)INT_MAX;
 9     CGFloat green = arc4random() / (CGFloat)INT_MAX;
10     CGFloat blue = arc4random() / (CGFloat)INT_MAX;
11     self.colorLayer.backgroundColor = [UIColor colorWithRed:red green:green blue:blue alpha:1.0].CGColor;
12//commit the transaction
13     [CATransaction commit];
14 }

 

如果你用過UIView的動畫方法做過一些動畫效果,那麼應該對這個模式不陌生。UIView有兩個方法,+beginAnimations:context:+commitAnimations,和CATransaction+begin+commit方法類似。實際上在+beginAnimations:context:+commitAnimations之間所有視圖或者圖層屬性的改變而做的動畫都是由於設置了CATransaction的原因。

在iOS4中,蘋果對UIView添加了一種基於block的動畫方法:+animateWithDuration:animations:。這樣寫對做一堆的屬性動畫在語法上會更加簡單,但實質上它們都是在做同樣的事情。

CATransaction+begin+commit方法在+animateWithDuration:animations:內部自動調用,這樣block中所有屬性的改變都會被事務所包含。這樣也可以避免開發者由於對+begin+commit匹配的失誤造成的風險。

 


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

-Advertisement-
Play Games
更多相關文章
  • 直接寫解決方法吧: 1、將XML里的靜態引入刪除: 2、在代碼里 findViewById 找到 NavigationView,然後引入 Header 和 Menu,再獲取頭部佈局,最後設置監聽事件: 3、完整代碼如下: ...
  • 動畫速度 動畫實際上就是一段時間內的變化,這就暗示了變化一定是隨著某個特定的速率進行。速率由以下公式計算而來: 這裡的變化可以指的是一個物體移動的距離,時間指動畫持續的時長,用這樣的一個移動可以更加形象的描述(比如position和bounds屬性的動畫),但實際上它應用於任意可以做動畫的屬性(比如 ...
  • #CAMediaTiming`協議 CAMediaTiming協議定義了在一段動畫內用來控制逝去時間的屬性的集合,CALayer和CAAnimation都實現了這個協議,所以時間可以被任意基於一個圖層或者一段動畫的類控制。 持續和重覆 我們在第八章“顯式動畫”中簡單提到過duration(CAMed ...
  • 在動畫過程中取消動畫 之前提到過,你可以用-addAnimation:forKey:方法中的key參數來在添加動畫之後檢索一個動畫,使用如下方法: 但並不支持在動畫運行過程中修改動畫,所以這個方法主要用來檢測動畫的屬性,或者判斷它是否被添加到當前圖層中。 為了終止一個指定的動畫,你可以用如下方法把它 ...
  • Feature: 點擊選擇拍照或者打開相冊,選取圖片進行裁剪最後設置為圓形頭像。 Problem: 拍好照片,點擊裁剪,彈Toast“無法載入此圖片”。 Solution: 在裁剪的class裡加兩行代碼 主要代碼如下: ...
  • 屬性動畫 CAAnimationDelegate在任何頭文件中都找不到,但是可以在CAAnimation頭文件或者蘋果開發者文檔中找到相關函數。在這個例子中,我們用-animationDidStop:finished:方法在動畫結束之後來更新圖層的backgroundColor。 當更新屬性的時候, ...
  • 呈現與模型 CALayer的屬性行為其實很不正常,因為改變一個圖層的屬性並沒有立刻生效,而是通過一段時間漸變更新。這是怎麼做到的呢? 當你改變一個圖層的屬性,屬性值的確是立刻更新的(如果你讀取它的數據,你會發現它的值在你設置它的那一刻就已經生效了),但是屏幕上並沒有馬上發生改變。這是因為你設置的屬性 ...
  • 圖層行為 現在來做個實驗,試著直接對UIView關聯的圖層做動畫而不是一個單獨的圖層。清單7.4是對清單7.2代碼的一點修改,移除了colorLayer,並且直接設置layerView關聯圖層的背景色。 清單7.4 直接設置圖層的屬性 1 @interface ViewController () 2 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...