標籤:core animation catransitoin catransaction
圖層的內容動畫
Core Animation提供的基礎設施讓輕鬆建立複雜圖層動畫變得異常簡單,Core Animation擴充了所有擁有圖層的視圖。例如改變圖層架構矩形的尺寸,改變其在螢幕上的位置,應用旋轉變換,改變它的透明度。使用Core Animation初始化一個動畫和改變屬性一樣簡單,但你也可以顯式的建立一個動畫並設定動畫的參數。
用簡單的動畫表現圖層屬性的變化
你可以以顯式或隱式的執行簡單的動畫。隱式動畫使用預設的定時器和動畫屬性展現動畫。而顯式動畫需要你為動畫對象配置一些參數。所以當預設的定時器能夠很好的為你服務並且你所要的動畫效果不需要太多代碼時,隱式動畫則非常的適合你。
簡單的動畫包括改變一個圖層的屬性,以及隨著時間的推移,讓Core Animation以動畫的形式展現這些屬性的變化。圖層定義了許多會影響圖層可視外觀的屬性。改變這些屬性是以動畫方式展現外觀變化的一種方式。例如將圖層的透明度從1.0修改為0.0,這將引起圖層的淡出特效,最後圖層變為透明。
重要:雖然你可以使用Core Animation介面直接讓支援圖層的視圖產生動畫,但這樣做經常需要額外的步驟。
為了觸發隱式動畫,你所要做的是更新圖層對象的屬性。當更改的目標是圖層樹中的圖層對象,更改將立即反映到對象上。而圖層對象的可視外觀並不會立即發生變化,Core Animation將圖層對象屬性的變化當做是一個觸發器,用以建立和安排一個或多個可執行檔隱式動畫。如清單3-1那樣修改圖層對象屬性,將引起Core Animation為你建立動畫對象,動畫對象將被安排在下一次更新周期運行。
清單3-1 隱式動畫的方式呈現圖層屬性的變化
theLayer.opacity = 0.0;
為了顯式地使用動畫對象呈現相同的變化,建立一個CABasicAnimation對象並配置該對象的動畫參數。在添加動畫到圖層之前,你可以設定動畫的開始值與結束值,改變期間,或任何其他動畫參數。你指定你想要動畫的屬性的鍵路徑,接著設定動畫參數。為了執行一個動畫,你使用addAnimation:forKey:方法將動畫對象添加到你想要展現動畫的圖層上。
清單3-2 顯式動畫的方式呈現圖層屬性的變化
CABasicAnimation* fadeAnimation = [CABasicAnimation animationWithKeyPath:@”opacity”;fadeAnimation.fromValue = [NSNumber numberWithFloat:1.0];fadeAnimation.toValue = [NSNumber numberWithFloat:0.0];fadeAnimation.duration = 1.0;[theLayer addAnimation:fadeAnimation forKey:nil];//改變圖層實際的最後資料值theLayer.opacity = 0.0; // 記得更新圖層樹
注意:建立一個顯示動畫,推薦是賦值一個值給動畫對象的fromValue屬性。如果你沒有為該屬性指定值,Core Animation將使用圖層的當前值作為開始值。如果已經更新了屬性作為它的最終值,這將致使fromValue屬性值遭到幹擾,結果可能並不是你想要的。
不同於隱式動畫,隱式動畫會更新圖層對象的值。而顯示動畫不會更改圖層樹中的資料。顯示動畫僅是建立了一個動畫。在動畫結束之後,Core Animation從圖層中移除該動畫對象並使用當前的資料值重繪圖層。如果你想讓顯示動畫的改變成為永久性的,如你在之前的例子中看到的,你必須更新圖層屬性。
隱式和顯示動畫都會在當前運行重複持續時間結束之後開始執行,並且當前的線程必須擁有一個用於執行動畫的運行迴圈runloop。如果你改變了圖層的動畫屬性或者給圖層添加了多個動畫對象。所有這些動畫將會同時被執行。例如將圖層移動到螢幕之外的時候添加漸隱動畫,這兩個動畫是同時啟動並執行。然而你可以讓動畫對象在一個特殊的時間開始執行。
CATransition 和 CATransaction
過渡動畫支援改變圖層的可視性
按字面上理解,一個過渡動畫對象為圖層建立一個可動畫的可視過渡。最普遍的過渡對象用法是動畫一個圖層的顯現和消失。與基於屬性的動畫不同,一個過渡動畫操縱一個圖層的緩衝圖片以建立可視效果,如果通過單獨的改變屬性實現會非常的困難,也許根本無法實現。標準的過渡類型包括:將舊視圖移開顯示新視圖、推入、移動、淡入淡齣動畫。在OS X上,你也可以使用Core Image過濾器建立使用其他特效類型,比如擦除、翻頁、波紋、或你設計的自訂特效的過渡。
為了實現一個一個過渡動畫,建立一個CATransition對象,然後添加該對象到包含過渡特效的圖層上。你使用過渡對象指定所要執行的過渡類型以及過渡動畫的開始點和結束點。你也可以不讓過渡動畫完整的執行。過渡對象讓你指定動畫啟動並執行開始和結束進度值。這些值可以使動畫在過渡的中間點開始或結束。
清單5-1用於在兩個視圖之間建立一個可動畫的推入過渡。在例子中,myView1和myView2被放置在相同父視圖中的相同位置,但只有myView1是當前可視的。推入過渡引起myView1一邊漸隱一邊向左滑出,直到它被隱藏,而myView2從右側滑入變成可視。更新兩個視圖的隱藏屬性確保兩個視圖的可視性在動畫的結尾是正確的。對一個圖層應用推入過渡,第一個滑出的圖層的使用當前的可視性,而右側滑入的圖層使用最後修改後的可視性。
清單5-1 iOS中得兩個視圖間的過渡特效
CATransition* transition = [CATransition animation];transition.startProgress = 0;transition.endProgress = 1.0;transition.type = kCATransitionPush;transition.subtype = kCATransitionFromRight;transition.duration = 0.5;// 為兩個圖層加入過渡動畫[_myView1.layer addAnimation:transition forKey:@"transition"];[_myView2.layer addAnimation:transition forKey:@"transition"];// 最後,改變圖層的可視性_myView1.hidden = !_myView1.hidden;_myView2.hidden = !_myView2.hidden;
當兩個圖層包含相同的過渡特效,你可以對兩個圖層應用同一個過渡對象。使用相同的過渡對象也簡化了代碼。然而,你也可以使用不同的過渡對象並且如果對每個圖層過渡參數都是不同的,那麼就肯定需要使用兩個不同的過渡對象。
清單5-2展示了在OS X平台上,如何使用Core Image過濾器實現一個過渡特效。配置帶有你想要的參數的過濾器後,將過濾器賦值給過渡對象的filter屬性,在完成這些之後,對動畫的使用和其他類型的動畫對象的使用是一樣的。
清單5-2 在OS X平台,使用Core Image過濾器動畫一個過渡特效
// Create the Core Image filter, setting several key parameters. CIFilter* aFilter = [CIFilter filterWithName:@"CIBarsSwipeTransition"]; [aFilter setValue:[NSNumber numberWithFloat:3.14] forKey:@"inputAngle"]; [aFilter setValue:[NSNumber numberWithFloat:30.0] forKey:@"inputWidth"]; [aFilter setValue:[NSNumber numberWithFloat:10.0] forKey:@"inputBarOffset"]; // Create the transition object CATransition* transition = [CATransition animation]; transition.startProgress = 0; transition.endProgress = 1.0; transition.filter = aFilter; transition.duration = 1.0; [self.imageView2 setHidden:NO]; [self.imageView.layer addAnimation:transition forKey:@"transition"]; [self.imageView2.layer addAnimation:transition forKey:@"transition"]; [self.imageView setHidden:YES];
注意:當在動畫中使用Core Image過濾器時,配置過濾器是技巧性最強的地方。比方說,使用欄擦除過渡特效,指定一個輸入角度,如果角度過大或過小可能導致沒有過渡特效發生。如果你沒有看到你期望的動畫,嘗試將你的過濾器參數調整為不同的值再運行查看。
明確交易可以改變動畫的參數
對圖層屬性的每次更改都是事務的一部分。CATransaction類管理動畫的建立和分組並在適當的時間執行動畫。在大部分情況下,你不需要建立你自己的事務。無論什麼時候,給圖層添加顯式或隱式動畫,Core Animation會自動建立一個隱含交易。然而你也可以建立明確交易以能夠更精確的管理動畫。
使用CATransaction類提供的方法建立與管理事務。通過調用begin類方法,可以開始(或隱式地建立)一個新的事務;調用commit類方法可結束一個事務。兩個方法之間的代碼就是作為事務部分的變化。比如說,改變一個圖層的兩個屬性,你可以使用清單5-5所示代碼。
清單5-5 建立明確交易
[CATransaction begin];theLayer.zPosition = 200.0;theLayer.opacity = 0.0;[CATransitoin commit];
使用事務的主要一個原因是明確交易的限制內,你可以改變動畫的期間,定時函數以及其他參數。你也可以賦值一個完成塊給整個事務,這樣當動畫組完成後能夠得到一個通知。改變動畫參數須要在事務字典中使用setValue:forKey:方法更改適當的鍵。比如說,為了改變預設的期間為10秒,則你需要改變kCATransactionAnimationDuration鍵,如清單5-6所示。
清單5-6 改變動畫預設的期間
[CATransaction begin];[CATransaction setValue:[NSNumber numberWithFloat:10.0f];forKey:kCATransactionAnimationDuration];[CATransaction commit];
在你想提供不同預設值給不同的動畫集合的情況下你可以內嵌事務。為了一個事務中內嵌一個事務,僅需要再次調用begin類方法。每一個begin類方法必須有一個與之配對的commit類方法。僅在你提交了對最外層事務的變化之後,Core Animation開始相關的動畫。
清單5-7顯式了一個事務中嵌套另一個事務的例子,內層的事務改變與外層的事務相同的動畫屬性,但是使用不同的值。
清單5-7 內嵌明確交易
[CATransaction begin]; // Outer transaction // Change the animation duration to two seconds [CATransaction setValue:[NSNumber numberWithFloat:2.0f] forKey:kCATransactionAnimationDuration]; // Move the layer to a new position theLayer.position = CGPointMake(0.0,0.0); [CATransaction begin]; // Inner transaction // Change the animation duration to five seconds [CATransaction setValue:[NSNumber numberWithFloat:5.0f] forKey:kCATransactionAnimationDuration]; // Change the zPosition and opacity theLayer.zPosition=200.0; theLayer.opacity=0.0; [CATransaction commit]; // Inner transaction [CATransaction commit]; // Outer transaction