今天,Cocoachina會開始一個Core Animation的入門教學,和大家共同學習Core Animation的使用。本站介紹過不少Core Animation的文章,這篇文章是一個入門教學,從頭幫助你了解Core Animation以及如何入門。

Cocoachina教學:Core Animation入門

Core Animation是蘋果在Leopard中加入的新API,主要用于利用顯卡硬件制作動態的用戶界面。同時,在iPhone SDK中也支持這種API。在Leopard和iPhone中,你會看到蘋果大量使用這種很酷的效果,比如iTunes/iPhone的 CoverFlow效果:

? Cocoachina教學:Core Animation入門

Core Animation的好處

????? Core Animation的最大好處是可以幫助Mac或者iPhone的開發者減少代碼量。

????? 因為如果你想用Core Image或者Open GL實現界面的動畫特效,其實也是可以的,主要是非常麻煩。而用Core Animation可以極大簡化開發難度和減少代碼量。

?

????? 如果你想用Core Animation建立你自己獨特的用戶界面,首先強烈建議你有一點藝術感,單單會使用Core Animation不能讓你成為藝術家。另外,你最好會用一點Adobe Photoshop或者Adobe Flash,在實現效果之前,先動手畫一畫,心里大致有個感覺。

?

????? 本文不會涉及到太深的技術或是數學算法層面,作者本人在這方面非常不精通。本文只是簡單地把你從蘋果晦澀的技術文檔中解救出來,看過這篇文章后你應該可以開始直接在程序里使用Core Animation了。

需要了解哪些

????? 閱讀本文之前,最好你已經有一點Cocoa開發的基礎,本文不會詳述細節。首先,你需要了解Objective-C,如果不了解,可以先看一下本站的新手文章:

另外你還要了解一點Objective-C 2.0的屬性說得是什么。同時,你需要了解如何使用XCode,這是比較基本的。

開始

?????? 要在Cocoa程序中使用Core Animation,首先要在程序中引用Quartz.framework,另外在.h文件中需要包含

?

      #import <Quartz/Quartz.h>
    
?

?

這樣就可以使用了。

?

?????? Core Animation繪圖的基礎是“層”,叫做CALayer。

?????? 你可以在View中設置層,層中可以放置更多的層。每個層都可以設定單獨的動作,還可以給上 一級的層設置動作,下一級的層就可以跟著上一層進行動作。

?

iPhone官方SDK同樣支持CALayer,而在底層的Toolchain中,你需要用的類 叫做LKLayer(Layer Kit),其實是一樣的。

?

????? Core Animation動畫的基礎主要是CAAnimation和CATransition,CAAnimation主要用于設定層的動作,比如放大縮小旋轉等等,而CATransition主要用于比如設置漸變、翻頁、切換等一些比較特殊的特效。

?

?????? Core Animation的動畫是基于View的,最簡單的用法是使用View的animator,修改一下View對象的屬性,但是消息發給對象的animator即可。

?

比如從前你可能這么寫:

                   [我的一個view set數值:xx];
    
?

那么你現在如果這么寫:

?

                   [[我的一個view animator] set數值:xx];
    
?

?

它就會動。

?

????? 想在View中打開Core Animation支持,你可以用以下方法實現:

??????????? [我的view setWantsLayer : YES ];

或是

?????????? 我的view. ?setWantsLayer = ?YES ;??????????????????? 這是Objective C 2.0的寫法

再或者

?????????? 在Interface Builder中打開這個選項:

Cocoachina教學:Core Animation入門

?

創建支持Core Animation的View

?

接下來用一個簡單的例子介紹一下如何做一個基于層的View用來支持Core Animation。

?

首先在Interface Builder里拽一個Custom View,拽進窗口,改名,隨便叫什么,比如我改為TestView:

Cocoachina教學:Core Animation入門

?

在菜單中選擇Write Class…,保存到項目中。你就可以在這個View里面做點能動的東西了。

?

在層中畫圖

?

??????? 你 可以直接在View里面使用 drawLayer: 方法畫層。不過一般來說,我們都會在層中使用一些圖片。

??????? 要給CALayer設置圖片,你只需使用 xxlayer.contents指定contents的屬性為一個圖片就可以在層上顯示圖片 。只是CALayer需要的圖片類型是 CGImageRef ,而我們比較容易獲取的圖片類型是NSImage。你可以使用下面的函數將NSImage轉換為 CGImageRef

?

      - (CGImageRef )nsImageToCGImageRef:(NSImage *)image;
{
    NSData * imageData = [image TIFFRepresentation ];
    CGImageRef imageRef;

    if (imageData)
    {
        CGImageSourceRef imageSource = CGImageSourceCreateWithData((CFDataRef )imageData,  NULL );
        
        imageRef = CGImageSourceCreateImageAtIndex(  imageSource, 0 , NULL );
    }
    return imageRef;
}
    
?

把這個函數復制到你的View代碼中,我們會需要用到它。

?

現在我們來做一個方法,叫做setupLayers:


      -(void ) setupLayers
  {

          }
    
?

?

然后在你的awakeFromNib中加入

?

                     [ self  setupLayers]; 
    
?

???????? 我們會在setupLayers這個方法中建立層,別忘了在你的.h文件中也加入這個方法的定義。

接下來,在項目中添加一個圖片,比如我叫它1.png,我會在層中顯示這個圖片:

?

? Cocoachina教學:Core Animation入門

?

加入之后,在setupLayers方法中加入下面幾句話:

?

      -(void ) setupLayers
{          
   CGRect viewFrame= NSRectToCGRect([ self frame]);
   CALayer *rootLayer=self .layer; 
   rootLayer.frame=viewFrame;
}
    
?

?

這三句話的意思是:

????????? 獲得這個View本身的層,并將其大小設定為view的大小。這個層就是我們的基礎層,我們之后添加的層會在這個rootLayer之上。

?

定義一個CALayer:

      CALayer * layer1 ;?

    

然后創建這個層:

      layer1 =[ CALayer layer] ; 
    
?

?

然后獲取我們剛才加進項目的圖片:

      NSImage *image1=[ NSImage imageNamed: @"1" ] ;?
    

把這個圖片設置在layer1上顯示:

      layer1 .contents=(id )[self  nsImageToCGImageRef :image1];?
    

設置層的大小和位置:

      layer1 .frame=CGRectMake (0 ,0 ,320 ,240 );
layer1 . position= CGPointMake(viewFrame. size. width/ 2 , viewFrame. size. height/ 2 ); // 定位到屏幕中間
    

添加到rootLayer上:


      [rootLayer addSublayer :layer1 ];
    

這幅圖片就顯示出來了:

Cocoachina教學:Core Animation入門

在你那里看起來和這幅圖不一樣的原因是我畫了一下背景:


      - (void )drawRect:(NSRect )rect 
  { //畫背景
NSGradient *gradient=[[ NSGradient alloc] initWithStartingColor: [ NSColor colorWithCalibratedWhite: 0.35 alpha: 1.0 ] 
endingColor:[ NSColor colorWithCalibratedWhite: 0 alpha: 1.0 ]];
[gradient drawInRect :rect angle :90.0 ];

   }
    
?

????? View的drawRect:方法可以和Core Animation并存 ,因此你的程序會先畫出這個漸變的背景,然后在上面畫這個帶圖片的層。

?

開始動畫

這個教學里我暫時不打算說太多復雜的內容,先來點能看到實際效果的東西。我們將這幅圖橫向旋轉一下,這個效果有點像Dashboard中進行設置的感覺:

?

添加下面的代碼:


      -(void )flip

{

[ CATransaction setValue:[ NSNumber numberWithFloat: 1.0 ] forKey: kCATransactionAnimationDuration];

CABasicAnimation *FlipAnimation=[ CABasicAnimation animationWithKeyPath: @"transform.rotation.y" ];

FlipAnimation.timingFunction= [ CAMediaTimingFunction functionWithName: kCAMediaTimingFunctionEaseInEaseOut];

FlipAnimation.toValue= [NSNumber numberWithFloat :M_PI ]; 

FlipAnimation.duration=1 ;

FlipAnimation.fillMode=kCAFillModeForwards ;

FlipAnimation.removedOnCompletion=NO ;

[layer1 addAnimation :FlipAnimation forKey :@"flip" ];

[ CATransaction commit];

}
    
?

???????? 在layer1 addAnimation的時候,動畫就加進去并自動運行了。這段代碼的意思是延y軸將layer1旋轉180度,持續時間1秒,旋轉完成后保持狀態。

?

“transform.rotation.y”?? 你可以在Core Animation的文檔中查到,用于旋轉y軸。

?

FlipAnimation.toValue= [ NSNumber ? numberWithFloat : M_PI ];?

?

中的M_PI就是pi,因為旋轉角度使用弧度而不是角度,所以pi就是半個圓,也就是180度。

?

?

FlipAnimation.fillMode= kCAFillModeForwards ;

FlipAnimation.removedOnCompletion= NO ;

而上面這兩句話的意思就是旋轉之后保持狀態。否則旋轉的動畫完成之后,動畫將自動刪除,而你的層也會回到初始狀態。

?

?

在awakeFromNib中加入下面代碼執行:

[ self flip ];

?

執行之后你就會看到這幅圖片按照動畫的效果橫向旋轉了180度。

?

Cocoachina教學:Core Animation入門