iOS CoreAnimation
為什么80%的碼農都做不了架構師?>>> ??
前言:這篇文章太全了,忍不住就轉了,原地址?CoreAnimation,另外前面寫過一篇簡單的動畫IOS簡單動畫
核心動畫,開發人員可以為他們的應用創建動態用戶界面,而無需使用低級別的圖形 API,如 OpenGL 來獲取高效的動畫性能。?
前言,核心動畫的好處
1.簡單易用的高性能混合編程模型。
2.類似視圖一樣,你可以通過使用圖層來創建復雜的接口。? ?通過是CALayer來使用更復雜的一些動畫。? ?
3.輕量級的數據結構,它可以同時顯示并讓上百個圖層產生動畫效果。? ? ?控制多個CALayer來顯示動畫效果? ? ???
4.一套簡單的動畫接口,可以讓你的動畫運行在獨立的線程里面,并可以獨立于主線程之外。
5.一旦動畫配置完成并啟動,核心動畫完全控制并獨立完成相應的動畫幀。
6.提高應用性能。應用程序只當發生改變的時候才重繪內容。再小的應用程序也需要改變和提供布局服務層。核心動畫還消除了在動畫的幀速率上運行的應用程序代碼。
7.靈活的布局管理模型。包括允許圖層相對同級圖層的關系來設置相應屬性的位置和大小。? ?可以使用CALayer來更靈活的進行布局。??
1.1 Core animation類
1.提供顯示內容的圖層類。CALayer
2.動畫和計時類。Animation and Timing Classes
3.布局和約束類。
4.事務類,在原子更新的時候組合圖層類。核心動畫的基礎類包含在 Quartz 核心框架(Quartz Core framework)里面,雖然它的其他圖層類在其他框架里面定義。下圖顯示了核心動畫的類層次結構。?
?1.1.1 圖層類? ?
層類(Layer Classes)?
?Layer Classes是core animation的基礎。Layer Classes提供了一個抽象的概念,這個概念對于那些使用NSview和UIview的開發者來說是很熟悉的。基礎層是由CAlayer類提供的,CAlayer是所有Core Animation層的父類。?? ?
同一個視圖類的實例一樣,一個CAlayer實例也有一個單獨的superlayer和上面所有的子層(sublayers),它創建了一個有層次結構的層,我們稱之為layer tree。layers的繪制就像views一樣是從后向前繪制的,繪制的時候我們要指定其相對與他們的superlayer的集合形狀,同時還需要創建一個局部的坐標系。layers可以做一些更復雜的操作,例如rotate(旋轉),skew(傾斜),scale(放縮),和project the layer content(層的投影)。? ?
圖層的內容提供
(1)直接設置層的content屬性到一個core graphics圖,或者通過delegation來設置
(2)提供一個代理直接繪制到Core Graphics image context(核心圖形的上下文)
(3)設置任意數量的所有層共有的可視的風格屬性。例如:backgroundColor(背景色),opacity(透明度)和masking(遮罩)。max os x應用通過使用core image filters來達到這種可視化的屬性。
(4)子類化CAlayer,同時在更多的封裝方式中完成上面的任意技術。?
?
? 三個重要的子類
(1)CAScrollLayer:它是CALayer的一個子類,用來顯示layer的某一部分,一個CAScrollLayer對象的滾動區域是由其子層的布局來定義的。CAScrollLayer沒有提供鍵盤或者鼠標事件,也沒有提供明顯的滾動條。
(2)CATextLayer:它是一個很方便就可以從string和attributed string創建layer的content的類。
(3)CATiledLayer:它允許在增量階段顯示大和復雜的圖像(就是將圖形進行分塊顯示,來減少性能開銷)
?
? ?Mac OS X 額外的類CAOpenGLLayer 提供了一個OpenGL渲染環境。你必須繼承這個類來使用 OpenGL 提供的內容。內容可以是靜態的,或可隨著時間的推移更新。QCCompositionLayer(由Quartz框架提供)可以把Quartz合成的內容動畫 顯示。QTMovieLayer and QTCaptureLayer (QTKit 框架提供)提供播放 QuickTime 影片和視頻直播。
?
? ?iOS 獨特的CALayerCAEAGLLayer 提供了一個OpenGLES渲染環境。CALayer 的類引入鍵-值編碼兼容的容器類概念,也就是說一個類可以使用鍵 - 值編碼的方法存儲任意值,而無需創建一個子類。CALayer 的還擴展了 NSKeyValueCoding 的非正式協議,加入默認鍵值和額外的結構類型的自動對象包裝 (CGPoint,CGSize,CGRect,CGAffineTransform 和 CATransform3D)的支持,并 提供許多這些結構的關鍵路徑領域的訪問。CALayer也管理動畫和與其相關的layer的actions。layers接收一些從layer tree中觸發的insert和remove消息,修改被創建的layer的屬性,或者指明開發者的需求。這些actions通常都會導致動畫的產生。
?
1.1.2 動畫和計時類(Animation and Timing Classes)? ??
?????圖層的很多可視化屬性是可以隱式動畫的。通過簡單的改變圖層的可動畫顯示的屬性,可以讓圖層現有屬性從當前值動畫漸變到新的屬性值。例如設置圖層的 hidden 屬性為 YES 將會觸發動畫使層逐漸淡出。
? ??默認動畫?
? ?大多數動畫屬性擁有自己關聯的默認動畫, 你可以輕松地定制和替換。我們將會在后面“動畫屬性”部分列出一個完整的動畫屬性列表和它們相應的默認動畫。
? ?關于哪些屬性執行的是什么默認動畫效果請參考apple官方文檔?
? ?顯式動畫
? ?動畫的屬性也可以顯式動畫。要顯式動畫的屬性,你需要創建核心動畫動畫類的一個實例,并指定所需的視覺效果。顯式動畫不會改變該 、屬性的值,它只是用于動畫顯示。?
?
? ? 核心動畫的動畫類使用基本的動畫和關鍵幀動畫把圖層的內容和選取的屬性動畫的顯示出來。所有核心動畫的動畫類都是從 CAAnimation 類繼承而來。
CAAnimation 實現了 CAMediaTiming 協議,提供了動畫的持續時間,速度,和重復計數。 CAAnimation 也實現了 CAAction 協議。該協議為圖層觸發一個動畫動作提供了提供標準化響應。動畫類同時定義了一個使用貝塞爾曲線來描述動畫改變的時間函數。例如,一個 勻速時間函數(linear timing function)在動畫的整個生命周期里面一直保持速度不變, 而漸緩時間函數(ease-out timing function)則在動畫接近其生命周期的時候減慢速度。核心動畫額外提供了一系列抽象的和細化的動畫類,比如:CATransition 提供了一個圖層變化的過渡效果,它能影響圖層的整個內容。 動畫進行的時候淡入淡出(fade)、推(push)、顯露(reveal)圖層的內容。這些過渡效 果可以擴展到你自己定制的 Core Image 濾鏡。CAAnimationGroup 允許一系列動畫效果組合在一起,并行顯示動畫。
?
多個動畫效果疊加,比如在執行動畫的過程中需要同時修改position,alpha, frame等屬性,可以將三個動畫合成一起執行。
CAAnimationGroup?*animGroup?=?[CAAnimationGroup?animation];? animGroup.animations?=?[NSArray?arrayWithObjects:moveAnim,scaleAnim,opacityAnim,?nil]; animGroup.duration?=?1; [view.layer?addAnimation:animGroup?forKey:nil];CAPropertyAnimation 是一個抽象的子類,它支持動畫的顯示圖層的關鍵路 徑中指定的屬性一般不直接使用,而是使用它的子類,CABasicAnimation,CAKeyframeAnimation. 在它的子類里修改屬性來運行動畫。
?
CABasicAnimation 簡單的為圖層的屬性提供修改。?很多圖層的屬性修改默認會執行這個動畫類。比如大小,透明度,顏色等屬性
CAKeyframeAnimation 支持關鍵幀動畫,你可以指定的圖層屬性的關鍵路徑動畫,包括動畫的每個階段的價值,以及關鍵幀時間和計時功能的一系列值。在 動畫運行是,每個值被特定的插入值替代。核心動畫 和 Cocoa Animation 同時使用這些動畫類。使用動畫描述,是因為這些類涉及到核心動畫,這些將會在Animation Types and Timing Programming Guide 有較深入的討論。
?
1.1.3 布局管理器類
Application Kit 的視圖類相對于 superlayer 提供了經典的“struts and springs”定位 模型。圖層類兼容這個模型,同時 Mac OS X 上面的核心動畫提供了一套更加靈活 的布局管理機制,它允許開發者自己修改布局管理器。核心動畫的 CAConstraint 類 是一個布局管理器,它可以指定子圖層類限制于你指定的約束集合。每個約束 (CAConstraint 類的實例封裝)描述層的幾何屬性(左,右,頂部或底部的邊緣或水 平或垂直中心)的關系,關系到其同級之一的幾何屬性層或 superlayer。通用的布局管理器和約束性布局管理器將會在“布局核心動畫的圖層”部分討論。
?1.1.4 事務管理類?? ?
?圖層的動畫屬性的每一個修改必然是事務的一個部分。CATransaction 是核心動畫里面負責協調多個動畫原子更新顯示操作。事務支持嵌套使用。?????
第二章 核心動畫渲染框架?
可能有人會很好奇CoreAnimation是如何渲染動畫,動畫是如何生成的。?在core aniamtion和cocoa view之間有很大的相似之處,他們之間最大的概念上的分歧就是layer不直接渲染到屏幕上。在MVC的設計模式下,NSView和UIView是視圖對象,core animation層實際上是模型對象。他們封裝了幾何圖形,時間和可視屬性,同時提供顯示的內容,但是實際上顯示并不是layer的責任。每一個可視的layer tree后面都有兩個相應的tree:presentation tree和render tree。如下圖所示:
layer tree包含了每個layer的對象模型。當你為一個layer的屬性設置一個的時候,他們的值就是你設置的。The presentation tree包含了當前正在呈現給用戶作為動畫發生的值。例如:對一個layer的backgroundcolor設置一個新的值的時候,在layer tree中的值會馬上改變。然而,在presentation tree的相應層的backgroundcolor的值隨著要顯示給用戶的插值顏色會被更新。當渲染一個layer的時候,the render-tree會使用presentation-tree的值。the render-tree的責任就是執行獨立與程序活動的合成操作;渲染是在一個單獨進程或者線程中,以便使其對應用程序的run loop影響最小。當一個動畫在執行的過程中,你可以查詢相應的presentation layer的實例。如果你打算改變當前的動畫并且從當前顯示狀態開始一個新的動畫,這是非常有用的。???
第三章 ?圖層的幾何和變化
?
?圖層的幾何變化涉及到修改圖層的幾何屬性,比如大小,錨點,圓角等屬性等等,這個部分詳細的可以查看Quartz 2D 的文檔,這個文檔講的比較詳細。?
?3.1圖層的坐標系
圖層的坐標系在不同平臺上面具有差異性。在 iOS 系統中,默認的坐標系統原點 在圖層的中心左上角地方,原點向右和向下為正值。在 Mac OS X 系統中,默認的坐 標系原點在圖層的中心左下角地方,原點向右和向上為正值。坐標系的所有值都是浮 點類型。你在任何平臺上面創建的圖層都采用該平臺默認的坐標系。
每個圖層定義并維護自己的坐標系,它里面的全部內容都由此相關的坐標系指定 位置。該準則同時適應于圖層自己的內容和它的任何子圖層。因為任何圖層定義了它 自己的坐標系,CALayer 類提供相應的方法用于從一個圖層坐標系的點、矩形、大小 值轉化為另一個圖層坐標系相應的值。一些基于圖層的屬性使用單元坐標空間測量它們的值。單元坐標空間指定圖層邊 界的相對值,而不是絕對值。單元坐標空間給定的 x 和 y 的值總是在 0.0 到 1.0 之間。 指定一個沿 X 軸的值為 0.0 的點,得到的是圖層左邊緣的一個點,而指定一個 1.0 的點,則是圖層右邊緣的一個點。(對 Y 軸而言,如果是在 iOS 系統,則 0.0 對應于 頂部的點,而 1.0 則是底部的點,而在 Mac OS X 系統,得到的剛好相反,就如之前 提到的坐標系不同一樣)。而點(0.5,0.5)則剛好是圖層的中心點。
?
?3.2指定圖層的幾何
雖然圖層和圖層樹與視圖和視圖的結構在很多方面具有相似性,但是圖層的幾何 卻不同,它更加簡單通俗。圖層的所有幾何屬性,包括圖層的矩陣變換,都可以隱式 和顯式動畫。
? 下圖顯示可以在上下文中指定圖層幾何的屬性:?
圖層的 position 屬性是一個 CGPoint 的值,它指定圖層相當于它父圖層的位置, 該值基于父圖層的坐標系。圖層的 bounds 屬性是一個 CGRect 的值,指定圖層的大小(bounds.size)和圖層的 原點(bounds.origin)。當你重寫圖層的重畫方法的時候,bounds 的原點可以作為圖形 上下文的原點。圖層擁有一個隱式的 frame,它是 position,bounds,anchorPoint 和 transform 屬性 的一部分。設置新的 frame 將會相應的改變圖層的 position 和 bounds 屬性,但是 frame 本身并沒有被保存。但是設置新的 frame 時候,bounds 的原點不受干擾,bounds 的大 小變為 frame 的大小,即 bounds.size=frame.size。圖層的位置被設置為相對于錨點 (anchor point)的適合位置。當你設置 frame 的值的時候,它的計算方式和 position、 bounds、和 anchorPoint 的屬性相關。圖層的 anchorPoint 屬性是一個 CGPoint 值,它指定了一個基于圖層 bounds 的符 合位置坐標系的位置。錨點(anchor point)指定了 bounds 相對于 position 的值,同 時也作為變換時候的支點。錨點使用單元空間坐標系表示,(0.0,0.0)點接近圖層 的原點,而(1.0,1.0)是原點的對角點。改變圖層的父圖層的變換屬性(如果存在 的話)將會影響到 anchorPoint 的方向,具體變化取決于父圖層坐標系的 Y 軸。?當你設置圖層的 frame 屬性的時候,position 會根據錨點(anchorPoint)相應的改 變,而當你設置圖層的 position 屬性的時候,bounds 會根據錨點(anchorPoint)做相應的改變。?
?
下圖描述了基于錨點的三個示例值:
anchorPoint 默認值是(0.5,0.5),位于圖層邊界的中心點(如上圖顯示),B 點 把 anchorPoint 設置為(0.0,0.5)。最后 C 點(1.0,0.0)把圖層的 position 設置為 圖層 frame 的右下角。該圖適用于 Mac OS X 的圖層。在 iOS 系統里面,圖層使用不 同的坐標系,相應的(0.0,0.0)位于左上角,而(1.0,1.0)位于右下角。
圖層的 frame、bounds、position 和 anchorPoint 關系如下圖所示:?
在該示例中,anchorPoint 默認值為(0.5,0.5),位于圖層的中心點。圖層的 position 值為(100.0,100.0),bounds 為(0.0,0.0,120,80.0)。通過計算得到圖層的 frame為(40.0,60.0,120.0,80.0)。
如果你新創建一個圖層,則只有設置圖層的 frame 為(40.0,60.0,120.0,80.0),相應的 position 屬性值將會自動設置為(100.0,100.0),而 bounds 會自動設置為 (0.0,0.0,120.0,80.0)。下圖顯示一個圖層具有相同的 frame(如上圖),但是在該圖中它的 anchorPoint 屬性值被設置為(0.0,0.0),位于圖層的左下角位置。
?
圖層的 frame 值同樣為(40.0,60.0,120.0,80.0),bounds 的值不變,但是圖層的 position 值已經改變為(40.0,60.0)。
圖層的幾何外形和 Cocoa 視圖另外一個不同地方是,你可以設置圖層的一個邊角 的半徑來把圖層顯示為圓角。圖層的 cornerRadius 屬性指定了重繪圖層內容,剪切子 圖層,繪制圖層的邊界和陰影的時候時候圓角的半徑。
圖層的 zPosition 屬性值指定了該圖層位于 Z 軸上面位置,zPosition 用于設置圖層 相對于圖層的同級圖層的可視位置
3.3 圖層的幾何變換
圖層一旦創建,你就可以通過矩陣變換來改變一個圖層的幾何形狀。?CATransform3D 的數據結構定義一個同質的三維變換(4x4 CGFloat 值的矩陣),用于 圖層的旋轉,縮放,偏移,歪斜和應用的透視。圖層的兩個屬性指定了變換矩陣:transform 和 sublayerTransform 屬性。圖層的 transform 屬性指定的矩陣結合圖層的 anchorPoint 屬性作用于圖層和圖層的子圖層上 面。圖 3 顯示在使用 anchorPoint 默認值(0.5,0.5)的時候旋轉和縮放變換如何影響一個圖層。而圖 4 顯示了同樣的矩陣變換在 anchorPoint 為(0.0,0.0)的時候如何改變一 個圖層。圖層的 sublayerTransform 屬性指定的矩陣只會影響圖層的子圖層,而不會對 圖層本身產生影響。你可以通過以下的任何一個方法改變 CATransform3D 的數據結構:(1) 使用CATransform3D函數(2) 直接修改數據結構的成員(3) 使用鍵-值編碼改變鍵路徑
CATransform3DIdentity 是單位矩陣,該矩陣沒有縮放、旋轉、歪斜、透視。把該 矩陣應用到圖層上面,會把圖層幾何屬性修改為默認值。?
?3.3.1 變換函數
使用變換函數可以在核心動畫里面在操作矩陣。你可以使用這些函數(如下表)去 創建一個矩陣一般后面用于改變圖層或者它的子圖層的 transform 和 sublayerTransform屬性。變換函數或者直接操或者返回一個CATransform3D的數據結 構。這可以讓你能夠構建簡單或復雜的轉換,以便重復使用。
核心動畫 提供了用于轉換矩陣的變換函數 CATransform3DInvert。一般是用反轉 點內轉化對象提供反向轉換。當你需要恢復一個已經被變換了的矩陣的時候,反轉將 會非常有幫助。反轉矩陣乘以逆矩陣值,結果是原始值。變換函數同時允許你把 CATransform3D 矩陣轉化為 CGAffineTransform(仿射) 矩陣,前提是 CATransform3D 矩陣采用如下表示方法。
變換函數同時提供了可以比較一個變換矩陣是否是單位矩陣,或者兩個矩陣是否 相等。
3.3.2 修改變換的數據結構
你可以修改 CATransform3D 的數據結構的元素為任何其他你想要的數據值。清單 1 包含了 CATransform3D 數據結構的定義,結構的成員都在其相應的矩陣位置。struct CATransform3D? ? ? ? ? ? ? ?{? ? ? ? ? ? ? ? ?CGFloat m11, m12, m13, m14;? ? ? ? ? ? ? ? ?CGFloat m21, m22, m23, m24;? ? ? ? ? ? ? ? ?CGFloat m31, m32, m33, m34;? ? ? ? ? ? ? ? ?CGFloat m41, m42, m43, m44;? ? ? ? ? ? ? ? ?};? ? ? ? ? ? ? ?typedef struct CATransform3D CATransform3D;? ? ? ? ? ? ? ?? ? ? ? ? ? ? ?清單 2 中的示例說明了如何配置一個 CATransform3D 一個角度變換。 ? ? ? ? ? ? ?
3.3.3 通過鍵值路徑修改變換? ?
核心動畫擴展了鍵-值編碼協議,允許通過關鍵路徑獲取和設置一個圖層的 CATransform3D 矩陣的值。表 4 描述了圖層的 transform 和 sublayerTransform 屬性的相應關鍵路徑。??
?你不可以通過 Objective-C 2.0 的屬性來設置結構域的值,比如下面的代碼將會無法正常運行:? ?? ?myLayer.transform.rotation.x=0;? ???? ?替換的辦法是,你必須通過 setValue:forKeyPath:或者 valueForKeyPath:方法, 具體如下:? ?? ? ? [myLayer setValue:[NSNumber numberWithInt:0] forKeyPath:@"transform.rotation.x"];
?
?3.4 圖層的操作
圖層有一個圖層樹,既然是樹,就允許添加,插入,刪除,替換相應的圖層,
?這些操作都可以通過已有的api實現,api如下
3.5 圖層的內容?
圖層的內容提供,是指通過一種方法來制定CALayer 實例的內容:?其中有一下三種方式來提供CAlayer的內容? (1)使用包含圖片內容的 CGImageRef 來顯式的設置圖層的 contents 的屬性。 ? (2)指定一個委托,它提供或者重繪內容。? (3)繼承 CALayer 類重載顯示的函數。
?
第四章 動畫動畫是當今用戶界面的關鍵因素。當使用核心動畫的時候,動畫是自動完成的。 沒有動畫的循環和計數器。你的應用程序不負負責重繪,也不負責跟蹤動畫的當前狀 態。動畫在獨立線程里面自動執行,沒有和你的應用程序交互。核心動畫提供了一套你可以在你應用程序里面使用的動畫類的表現:? (1)CABasicAnimation提供了在圖層的屬性值間簡單的插入。? (2)CAKeyframeAnimation 提供支持關鍵幀動畫。你指定動畫的一個圖層屬性的關鍵路徑,一個表示在動畫的每個階段的價值的數組,還有一個關鍵幀時間的數組和時間函數。? (3)CATransition提供了一個影響整個圖層的內容過渡效果。在動畫顯示過程中采用淡出(fade)、推出(push)、顯露(reveal)圖層的內容。 常用的過渡效果可以通過提供你自己定制的核心圖像濾鏡來擴展。除了要指定顯示的動畫類型,你還必須指定動畫的間隔、它的速度(它的插值如何分布在整個動畫過程)、動畫循環時候的循環次數、動畫周期完成的時候是否自動 的反轉、還有動畫結束的時候它的可視化狀態。動畫類和 CAMediaTiming 協議提供 所有這些功能甚至更多的功能。CAAnimation、它的子類、時序協議被核心動畫和Cocoa Animation Proxy功能共享。這些類將會在“動畫類型和時序編程指南(Animation Types and Timing Programming Guide)”里面詳細介紹。
? ? ? ? ? ? ?Core Animation 類的繼承關系圖?
?
下面將針對上面的知識做一個圖片動畫的demo
功能1 :移動圖片到右下角
//向右下角縮小移動-?(IBAction)buttonClick:(id)sender {CGPoint?fromPoint?=?imageView.center;????//路徑曲線????UIBezierPath?*movePath?=?[UIBezierPath?bezierPath];[movePath?moveToPoint:fromPoint];CGPoint?toPoint?=?CGPointMake(300,?460);[movePath?addQuadCurveToPoint:toPointcontrolPoint:CGPointMake(toPoint.x,fromPoint.y)];????//關鍵幀????CAKeyframeAnimation?*moveAnim?=?[CAKeyframeAnimation?animationWithKeyPath:@"position"];moveAnim.path?=?movePath.CGPath;moveAnim.removedOnCompletion?=?YES;????//旋轉變化????CABasicAnimation?*scaleAnim?=?[CABasicAnimation?animationWithKeyPath:@"transform"];scaleAnim.fromValue?=?[NSValue?valueWithCATransform3D:CATransform3DIdentity];????//x,y軸縮小到0.1,Z?軸不變????scaleAnim.toValue?=?[NSValue?valueWithCATransform3D:CATransform3DMakeScale(0.1,?0.1,?1.0)];scaleAnim.removedOnCompletion?=?YES;????//透明度變化????CABasicAnimation?*opacityAnim?=?[CABasicAnimation?animationWithKeyPath:@"alpha"];opacityAnim.fromValue?=?[NSNumber?numberWithFloat:1.0];opacityAnim.toValue?=?[NSNumber?numberWithFloat:0.1];opacityAnim.removedOnCompletion?=?YES;????//關鍵幀,旋轉,透明度組合起來執行????CAAnimationGroup?*animGroup?=?[CAAnimationGroup?animation];animGroup.animations?=?[NSArray?arrayWithObjects:moveAnim,?scaleAnim,opacityAnim,?nil];animGroup.duration?=?1;[imageView.layer?addAnimation:animGroup?forKey:nil]; }?功能2 :向右邊旋轉
?//向右邊旋轉-?(IBAction)rightRotateBtnClick:(id)sender {CGPoint?fromPoint?=?imageView.center;UIBezierPath?*movePath?=?[UIBezierPath?bezierPath];[movePath?moveToPoint:fromPoint];CGPoint?toPoint?=?CGPointMake(fromPoint.x?+100?,?fromPoint.y)?;[movePath?addLineToPoint:toPoint];CAKeyframeAnimation?*moveAnim?=?[CAKeyframeAnimation?animationWithKeyPath:@"position"];moveAnim.path?=?movePath.CGPath;CABasicAnimation?*scaleAnim?=?[CABasicAnimation?animationWithKeyPath:@"transform"];scaleAnim.fromValue?=?[NSValue?valueWithCATransform3D:CATransform3DIdentity];????//沿Z軸旋轉????scaleAnim.toValue?=?[NSValue?valueWithCATransform3D:?CATransform3DMakeRotation(M_PI,0,0,1)];????//沿Y軸旋轉???//?scaleAnim.toValue?=?[NSValue?valueWithCATransform3D:?CATransform3DMakeRotation(M_PI,0,1.0,0)];????//沿X軸旋轉??//?scaleAnim.toValue?=?[NSValue?valueWithCATransform3D:?CATransform3DMakeRotation(M_PI,1.0,0,0)];????scaleAnim.cumulative?=?YES;scaleAnim.duration?=1;??//旋轉2遍,360度????????scaleAnim.repeatCount?=2;imageView.center?=?toPoint;scaleAnim.removedOnCompletion?=?YES;CAAnimationGroup?*animGroup?=?[CAAnimationGroup?animation];animGroup.animations?=?[NSArray?arrayWithObjects:moveAnim,?scaleAnim,?nil];animGroup.duration?=?2;[imageView.layer?addAnimation:animGroup?forKey:nil];}功能3?:圖片旋轉360度
//圖片旋轉360度-?(IBAction)rota360BtnClick:(id)sender {CABasicAnimation?*animation?=?[?CABasicAnimationanimationWithKeyPath:?@"transform"?];animation.fromValue?=?[NSValue?valueWithCATransform3D:CATransform3DIdentity];????//圍繞Z軸旋轉,垂直與屏幕????animation.toValue?=?[?NSValue?valueWithCATransform3D:?CATransform3DMakeRotation(M_PI,?0,?0,?1.0)?];animation.duration?=?1;????//旋轉效果累計,先轉180度,接著再旋轉180度,從而實現360旋轉???animation.cumulative?=?YES;animation.repeatCount?=?2;????//在圖片邊緣添加一個像素的透明區域,去圖片鋸齒????CGRect?imageRrect?=?CGRectMake(0,?0,imageView.frame.size.width,?imageView.frame.size.height);UIGraphicsBeginImageContext(imageRrect.size);?[imageView.image?drawInRect:CGRectMake(1,1,imageView.frame.size.width-2,imageView.frame.size.height-2)];imageView.image?=?UIGraphicsGetImageFromCurrentImageContext();UIGraphicsEndImageContext();[imageView.layer?addAnimation:animation?forKey:nil]; }
---------------------------------------------------------------------------------------華麗的分割線---------------------------------------------------------------------------------------
CABasicAnimation 基本動畫
+(CABasicAnimation?*)opacityForever_Animation:(float)time?//永久閃爍的動畫
{
? ??CABasicAnimation?*animation=[CABasicAnimation?animationWithKeyPath:@"opacity"];
? ? animation.fromValue=[NSNumber?numberWithFloat:1.0];
? ? animation.toValue=[NSNumber?numberWithFloat:0.0];
? ? animation.autoreverses=YES;
? ? animation.duration=time;
? ? animation.repeatCount=FLT_MAX;
? ? animation.removedOnCompletion=NO;
? ? animation.fillMode=kCAFillModeForwards;
? ??return?animation;
}
?
+(CABasicAnimation?*)opacityTimes_Animation:(float)repeatTimes durTimes:(float)time;?//有閃爍次數的動畫
{
? ??CABasicAnimation?*animation=[CABasicAnimation?animationWithKeyPath:@"opacity"];
? ? animation.fromValue=[NSNumber?numberWithFloat:1.0];
? ? animation.toValue=[NSNumber?numberWithFloat:0.4];
? ? animation.repeatCount=repeatTimes;
? ? animation.duration=time;
? ? animation.removedOnCompletion=NO;
? ? animation.fillMode=kCAFillModeForwards;
? ? animation.timingFunction=[CAMediaTimingFunction?functionWithName:kCAMediaTimingFunctionEaseIn];
? ? animation.autoreverses=YES;
? ??return? animation;
}
?
+(CABasicAnimation?*)moveX:(float)time X:(NSNumber?*)x?//橫向移動
{
? ??CABasicAnimation?*animation=[CABasicAnimation?animationWithKeyPath:@"transform.translation.x"];
? ? animation.toValue=x;
? ? animation.duration=time;
? ? animation.removedOnCompletion=NO;
? ? animation.fillMode=kCAFillModeForwards;
? ??return?animation;
}
?
+(CABasicAnimation?*)moveY:(float)time Y:(NSNumber?*)y?//縱向移動
{
? ??CABasicAnimation?*animation=[CABasicAnimation?animationWithKeyPath:@"transform.translation.y"];
? ? animation.toValue=y;
? ? animation.duration=time;
? ? animation.removedOnCompletion=NO;
? ? animation.fillMode=kCAFillModeForwards;
? ??return?animation;
}
?
+(CABasicAnimation?*)scale:(NSNumber?*)Multiple orgin:(NSNumber?*)orginMultiple durTimes:(float)time Rep:(float)repeatTimes?//縮放
{
? ??CABasicAnimation?*animation=[CABasicAnimation?animationWithKeyPath:@"transform.scale"];
? ? animation.fromValue=orginMultiple;
? ? animation.toValue=Multiple;
? ? animation.duration=time;
? ? animation.autoreverses=YES;
? ? animation.repeatCount=repeatTimes;
? ? animation.removedOnCompletion=NO;
? ? animation.fillMode=kCAFillModeForwards;
? ??return?animation;
}
?
+(CAAnimationGroup?*)groupAnimation:(NSArray?*)animationAry durTimes:(float)time Rep:(float)repeatTimes?//組合動畫
{
? ??CAAnimationGroup?*animation=[CAAnimationGroup?animation];
? ? animation.animations=animationAry;
? ? animation.duration=time;
? ? animation.repeatCount=repeatTimes;
? ? animation.removedOnCompletion=NO;
? ? animation.fillMode=kCAFillModeForwards;
? ??return?animation;
}
?
+(CAKeyframeAnimation?*)keyframeAniamtion:(CGMutablePathRef)path durTimes:(float)time Rep:(float)repeatTimes//路徑動畫
{
? ??CAKeyframeAnimation?*animation=[CAKeyframeAnimation?animationWithKeyPath:@"position"];
? ? animation.path=path;
? ? animation.removedOnCompletion=NO;
? ? animation.fillMode=kCAFillModeForwards;
? ? animation.timingFunction=[CAMediaTimingFunction?functionWithName:kCAMediaTimingFunctionEaseIn];
? ? animation.autoreverses=NO;
? ? animation.duration=time;
? ? animation.repeatCount=repeatTimes;
? ??return?animation;
}
?
+(CABasicAnimation?*)movepoint:(CGPoint?)point?//點移動
{
? ??CABasicAnimation?*animation=[CABasicAnimation?animationWithKeyPath:@"transform.translation"];
? ? animation.toValue=[NSValue?valueWithCGPoint:point];
? ? animation.removedOnCompletion=NO;
? ? animation.fillMode=kCAFillModeForwards;
? ??return?animation;
}
?
+(CABasicAnimation?*)rotation:(float)dur degree:(float)degree direction:(int)direction repeatCount:(int)repeatCount?//旋轉
{
? ??CATransform3D?rotationTransform? =?CATransform3DMakeRotation(degree,?0,?0,direction);
? ??CABasicAnimation* animation;
? ? animation = [CABasicAnimation?animationWithKeyPath:@"transform"];
?
animation.toValue= [NSValue?valueWithCATransform3D:rotationTransform];
? ? animation.duration= dur;
animation.autoreverses=?NO;
? ? animation.cumulative=?YES;
? ? animation.removedOnCompletion=NO;
? ? animation.fillMode=kCAFillModeForwards;
? ? animation.repeatCount= repeatCount;?
animation.delegate=?self;
?
return?animation;
}
轉載于:https://my.oschina.net/wolx/blog/389778
總結
以上是生活随笔為你收集整理的iOS CoreAnimation的全部內容,希望文章能夠幫你解決所遇到的問題。