iOS Animation 學習(2)


UIImageView and UIImage Animation

UIImageView提供了形式很簡單的動畫,可能這些不值得一提,儘管如此,有時候它就是你所須要的所有。你給UIImageView 的 animationImages 或者 highlightedAnimationImages屬性 一個裝有UIImage 的NSArray值,這個數組表明一個簡單的動畫片「幀」。但你發送 startAnimating消息,圖片依次顯示,幀率由animationDuration屬性決定,重複次數由animationRepeatCount屬性決定(默認是0,意味着無限重複,或者直到收到 stopAnimating 消息)。在動畫以前和以後,這個UIImageView繼續顯示它的圖片(或者 highlightedImage)。數組

例如,假設咱們但願一張火星圖片從某個地方冒出來,並在屏幕上閃爍三次。這彷佛須要某種以NSTimer爲基礎的解決方案,但使用UIImageView的動畫就很是簡單:動畫

UIImage* mars = [UIImage imageNamed: @"Mars"];
UIGraphicsBeginImageContextWithOptions(mars.size, NO, 0);
UIImage* empty = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSArray* arr = @[mars, empty, mars, empty, mars];
UIImageView* iv = [[UIImageView alloc] initWithImage:empty];
CGRect r = iv.frame;
r.origin = CGPointMake(100,100);
iv.frame = r;
[self.view addSubview: iv];
iv.animationImages = arr;
iv.animationDuration = 2;
iv.animationRepeatCount = 1;
[iv startAnimating];

您能夠將UIImageView的動畫與其餘類型的動畫結合起來。例如,您能夠一邊閃爍火星圖像,而在同一時間向右滑動UIImageView,使用視圖的動畫將在後面看法。ui

此外,UIImage的動畫提供了並行的形式:圖像自己能夠是一個動畫對象。就像使用的UIImageView,這真的意味着你已經造成一個多張圖片的序列做爲一個簡單的動畫片「幀」。您可使用兩個UIImage的類方法之一來指定一個圖像做爲動畫對象:code

  • animatedImageWithImages:duration:orm

    如同UIImageView的的動畫圖片,你提供UIImages的數組。還爲整個動畫提供了動畫的持續時間。對象

  • animatedImageNamed:duration:圖片

    您提供的單個圖像文件的名稱,就像imageNamed:,不帶文件擴展名。運行時會爲您提供的名稱後面追加@「0」(或者,若是失敗了,@「1」),使該圖像文件爲動畫序列的第一個圖像。而後它遞增所附加的數字,獲取相應的圖像,並將它們添加到序列中(直到沒有更多圖片,或者咱們達到@「1024」)。ip

    還有一個第三方的方法:animatedResizableImageNamed:capInsets:resizing- Mode:duration:, 把可調整大小的圖片和動畫圖像結合起來。animation

你並不能告訴一個動畫形象開始執行動畫,也不能告訴它你想要動畫重複多久。相反,只要它出如今你的界面上,動畫圖像就始終在執行動畫,每隔1秒的時間重複這個圖片序列;爲了控制動畫,你能夠從你的界面中添加或者刪除這個圖像,這樣可能會讓動畫圖像轉變爲一個沒有動畫的圖像。此外,動畫圖像能夠出如今任何一個UIImage會出現的一些界面對象的屬性界面上。it

在這個例子中,我在代碼中構建了不一樣大小的紅色圓圈序列,並創建一個動畫形象,而後我在一個UIButton顯示:

NSMutableArray* arr = [NSMutableArray array];
float w = 18;
for (int i = 0; i < 6; i++) {
    UIGraphicsBeginImageContextWithOptions(CGSizeMake(w,w), NO, 0);
    CGContextRef con = UIGraphicsGetCurrentContext();
    CGContextSetFillColorWithColor(con, [UIColor redColor].CGColor);
    CGContextAddEllipseInRect(con, CGRectMake(0+i,0+i,w-i*2,w-i*2));
    CGContextFillPath(con);
    UIImage* im = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    [arr addObject:im];
}
UIImage* im = [UIImage animatedImageWithImages:arr duration:0.5];
// assume b is a button in the interface
[b setImage:im forState:UIControlStateNormal];

View Animation

動畫是最終層的動畫。可是,在有限的屬性範圍內,你能夠直接讓UIView執行動畫: 這些是它的 alpha, backgroundColor, bonds, center, frame 和 transform。 你也可讓UIView內容的變化執行動畫。這個名單儘管很簡單,可是一般已經足夠了。(若是執行不了動畫,你能夠用更加底層的技術,直接驅動 layer 來執行動畫,後面會見到。)

Block-Based View Animation

使用UIView類方法來使一個UIView執行動畫的語法,咱們通常使在block中描述咱們想要的動畫。例如,假設咱們在界面上有一個背景顏色爲黃色的UIView self.v ,咱們想要經過動畫來改變該視圖的背景顏色爲紅色。下面能夠作到這一點:

[UIView animateWithDuration:0.4 animations:^{
    self.v.backgroundColor = [UIColor redColor];
}];

在block中所作的變化都會執行動畫,因此咱們能夠經過動畫來同時改變視圖的位置和顏色:

[UIView animateWithDuration:0.4 animations:^{
    self.v.backgroundColor = [UIColor redColor];
    CGPoint p = self.v.center;
    p.y -= 100;
    self.v.center = p;
}];

可是,有時在block中的某些操做咱們不想讓它執行動畫,在 iOS 7 中,咱們可使用 performWithoutAnimation: 方法來解決這個問題。下面的代碼,視圖會跳到它的新位置,而後背景顏色慢慢地變爲紅色:

[UIView animateWithDuration:0.4 animations:^{
    self.v.backgroundColor = [UIColor redColor];
    [UIView performWithoutAnimation:^{
        CGPoint p = self.v.center;
        p.y -= 100;
        self.v.center = p;
    }]; 
}];

在block 中的代碼會要求執行動畫(不是performWithoutAnimation: block 中) -- 也就是,block中的代碼給出了在重繪時刻執行什麼樣的動畫。若是你把改變更畫視圖的某個屬性做爲動畫的一部分,那麼你在以後就不該該再改變它,不然結果會讓人很困惑。例如,猜猜下面的代碼會怎樣:

[UIView animateWithDuration:2 animations:^{
    CGPoint p = self.v.center;
    p.y = 100;
    self.v.center = p;
    CGPoint p2 = self.v.center;
    p2.y = 300;
    self.v.center = p2;
}];

結果並非兩個連續的動畫。咱們在這裏僅僅是一個動畫包含相互矛盾的命令: 經過動畫讓視圖的center 的 y 值變成 100、 經過動畫讓視圖的center 的 y 值變成300。 第二個動畫命令會致使第一個動畫被取消。 因此,但執行動畫時,視圖會跳到 center 的 y 值 爲100的位置,而後才以動畫的形式下移200。

即便在block 以後改變這個值也會形成迷惑。猜猜下面的代碼會怎樣:

[UIView animateWithDuration:2 animations:^{
    CGPoint p = self.v.center;
    p.y = 100;
    self.v.center = p;
}];
CGPoint p2 = self.v.center;
p2.y = 300;
self.v.center = p2;

這個動畫從它所在的位置開始,移動到center 的 y值爲300的地方! 在block裏面的代碼根本沒有執行。 跟在block後面的代碼至關於在block中執行,它已經成爲動畫的一部分了,實際的效果跟下面的代碼同樣:

[UIView animateWithDuration:2 animations:^{
    CGPoint p2 = self.v.center;
    p2.y = 300;
    self.v.center = p2;
}];
相關文章
相關標籤/搜索