事務(隱式動畫),事務動畫

來源:互聯網
上載者:User

事務(隱式動畫),事務動畫
事務

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)viewDidLoad11 {12     [super viewDidLoad];13     //create sublayer14     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 view18     [self.layerView.layer addSublayer:self.colorLayer];19 }20 21 - (IBAction)changeColor22 {23     //randomize the layer background color24     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 transaction13     [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匹配的失誤造成的風險。

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.