1. 程式人生 > >iOS中旋轉載入動畫的實現

iOS中旋轉載入動畫的實現

1.前言

近日一直在看KITTEN寫的《A GUIDE TO IOS ANIMATION》,此乃iOS動畫開發的聖經,簡直手不釋卷。其中有一個動畫是載入動畫,因為文中沒有給出實現的解析,我在這裡解析一下動畫的實現原理,和自己加入一些新的東西。Github地址


git1.gif

我們可以看到,圖中主要是3個球在做交換,其中中間的球基本保持位置不變,其他兩個球繞著一定的軌跡做旋轉位移動畫,接下來我們來看程式碼的實現步驟

2.三個球旋轉動畫

  1. 建立三個半徑大小,顏色大小一樣的圓。這裡我們用到了layer的cornerRadius屬性,在正方形中,我們只要設定cornerRadius的值等於height/2,就能輕易的畫出一個圓形,程式碼如下:

     UIView *ball_1 = [[UIView alloc] initWithFrame:CGRectMake(centerPoint.x - BALL_RADIUS, centerPoint.y, BALL_RADIUS, BALL_RADIUS)];
     ball_1.layer.cornerRadius = BALL_RADIUS / 2; // 成為圓形
     ball_1.backgroundColor = self.ballColor;
  2. 我們根據圓的x值不同,建立三個並排放著,大小、形狀一致的圓形,接下來我們來分析一下三個圓各自的x值


    [email protected]
     CGFloat
    centerPointY = HEIGHT / 2 - BALL_RADIUS * 0.5; CGFloat centerPointX = WIDTH / 2; CGPoint centerPoint = CGPointMake(centerPointX, centerPointY); UIView *ball_1 = [[UIView alloc] initWithFrame:CGRectMake(centerPoint.x - BALL_RADIUS, centerPoint.y, BALL_RADIUS, BALL_RADIUS)]; ball_1.layer.cornerRadius
    = BALL_RADIUS / 2; // 成為圓形 ball_1.backgroundColor = self.ballColor; [self addSubview:ball_1]; self.ball_1 = ball_1; UIView *ball_2 = [[UIView alloc] initWithFrame:CGRectMake(centerPoint.x - BALL_RADIUS * 0.5, centerPoint.y, BALL_RADIUS, BALL_RADIUS)]; ball_2.layer.cornerRadius = BALL_RADIUS / 2; // 成為圓形 ball_2.backgroundColor = self.ballColor; [self addSubview:ball_2]; self.ball_2 = ball_2; UIView *ball_3 = [[UIView alloc] initWithFrame:CGRectMake(centerPoint.x + BALL_RADIUS * 0.5, centerPoint.y, BALL_RADIUS, BALL_RADIUS)]; ball_3.layer.cornerRadius = BALL_RADIUS / 2; // 成為圓形 ball_3.backgroundColor = self.ballColor; [self addSubview:ball_3]; self.ball_3 = ball_3;

3.在git圖中,我們可以看到圓是繞著一定的半徑,做著一個旋轉的運動,在這裡我們用貝塞爾曲線創作圓,在這裡我們要從180度到360度,和0度到180畫兩端圓弧,組成一個圓形,讓球1跟著這個曲線做位移運動。


[email protected]
    // 2.1 第一個圓的曲線
    UIBezierPath *path_ball_1 = [UIBezierPath bezierPath];
    [path_ball_1 moveToPoint:centerBall_1];

    [path_ball_1 addArcWithCenter:centerPoint radius:BALL_RADIUS startAngle:M_PI endAngle:2*M_PI clockwise:NO];
    UIBezierPath *path_ball_1_1 = [UIBezierPath bezierPath];
    [path_ball_1_1 addArcWithCenter:centerPoint radius:BALL_RADIUS startAngle:0 endAngle:M_PI clockwise:NO];
    [path_ball_1 appendPath:path_ball_1_1]; // 把兩段圓弧組合起來

我們用核心動畫,讓球1繞著軌跡運動:

    // 2.2 第一個圓的動畫
    CAKeyframeAnimation *animation_ball_1=[CAKeyframeAnimation animationWithKeyPath:@"position"];
    animation_ball_1.path = path_ball_1.CGPath;
    animation_ball_1.removedOnCompletion = NO;
    animation_ball_1.fillMode = kCAFillModeForwards;
    animation_ball_1.calculationMode = kCAAnimationCubic;
    animation_ball_1.repeatCount = 1;
    animation_ball_1.duration = 1.4;
    animation_ball_1.delegate = self;
    animation_ball_1.autoreverses = NO;
    animation_ball_1.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    [self.ball_1.layer addAnimation:animation_ball_1 forKey:@"animation"];

這樣我們就完成了球1的動畫,我們按著這個步驟完成球3的動畫

4.球3首先是從0度到180度、180度到360度兩段弧構成,在這裡我們要注意一個點是在建立核心動畫的時候,我們不用再成為球3的核心動畫的代理,因為我們在球1中已經成為了動畫的代理,這裡不做代理,防止重複出現動畫代理事件的觸發


[email protected]
    // 2.3 第3個圓的曲線
        UIBezierPath *path_ball_3 = [UIBezierPath bezierPath];
    [path_ball_3 moveToPoint:centerBall_2];
    [path_ball_3 addArcWithCenter:centerPoint radius:BALL_RADIUS startAngle:0 endAngle:M_PI clockwise:NO];
    UIBezierPath *path_ball_3_1 = [UIBezierPath bezierPath];
    [path_ball_3_1 addArcWithCenter:centerPoint radius:BALL_RADIUS startAngle:M_PI endAngle:M_PI*2 clockwise:NO];
    [path_ball_3 appendPath:path_ball_3_1];

    // 2.4 第3個圓的動畫
    CAKeyframeAnimation *animation_ball_3 = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    animation_ball_3.path = path_ball_3.CGPath;
    animation_ball_3.removedOnCompletion = NO;
    animation_ball_3.fillMode = kCAFillModeForwards;
    animation_ball_3.calculationMode = kCAAnimationCubic;
    animation_ball_3.repeatCount = 1;
    animation_ball_3.duration = 1.4;
    animation_ball_3.autoreverses = NO;
    animation_ball_3.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];

    [self.ball_3.layer addAnimation:animation_ball_3 forKey:@"rotation"];

3.動畫的優化

在這裡我們實現了球1和球3繞著一個圓做旋轉位移運動,這裡我們已經完成了動畫的第一部分,我們來看一下效果圖:


gif2.gif


這裡我門可以看到只是單純的實現了球的旋轉位移,並不像一開始的git中的動畫一樣。讓我們一起來分析一下我們現在這個動畫距離第一個動畫還少了一些什麼:

  • git中的動畫在旋轉的時候球1和球2分別向兩邊位移了一段距離
  • 兩個球在向外位移的過程中還一邊縮小球的半徑
  • 球在旋轉的過程中,變回原來的位置,一邊變回原來的大小

在這裡我們要實現這3個動畫的補充,我們需要成為原來旋轉動畫的代理,也就是在球1的核心動畫設定delegate為self,監聽動畫開始的事件 - (void)animationDidStart:(CAAnimation*)anim,我們需要在動畫開始的時候完成3件事情,我們來看一下分析圖

1.動畫開始的時候球1和球3位移一定的距離,我們來看一下位移距離的量的計算圖


[email protected]
[email protected]
    self.ball_1.transform = CGAffineTransformMakeTranslation(-BALL_RADIUS, 0);        
    self.ball_3.transform = CGAffineTransformMakeTranslation(BALL_RADIUS, 0);

2.在位移的過程中,我們需要設定球1、球2、球3的大小,請看一下設定完位移和大小之後球1和球3的軌跡運動影象


[email protected]
    self.ball_1.transform = CGAffineTransformScale(self.ball_1.transform, 0.7, 0.7);

    self.ball_3.transform = CGAffineTransformScale(self.ball_3.transform, 0.7, 0.7);

    self.ball_2.transform = CGAffineTransformScale(self.ball_2.transform, 0.7, 0.7);

3.在一段時間後,把球1和球2的x值和size設為動畫前的大小,因此我們用UIView 的animation 動畫來完成這3個動畫

    [UIView animateWithDuration:0.3 delay:0.1 options:UIViewAnimationOptionCurveEaseOut|UIViewAnimationOptionBeginFromCurrentState animations:^{

    self.ball_1.transform = CGAffineTransformMakeTranslation(-BALL_RADIUS, 0);
    self.ball_1.transform = CGAffineTransformScale(self.ball_1.transform, 0.7, 0.7);

    self.ball_3.transform = CGAffineTransformMakeTranslation(BALL_RADIUS, 0);
    self.ball_3.transform = CGAffineTransformScale(self.ball_3.transform, 0.7, 0.7);


    self.ball_2.transform = CGAffineTransformScale(self.ball_2.transform, 0.7, 0.7);
    } completion:^(BOOL finished) {
    [UIView animateWithDuration:0.3 delay:0.1 options:UIViewAnimationOptionCurveEaseIn  | UIViewAnimationOptionBeginFromCurrentState animations:^{
        self.ball_1.transform = CGAffineTransformIdentity;
        self.ball_3.transform = CGAffineTransformIdentity;
        self.ball_2.transform = CGAffineTransformIdentity;
    } completion:NULL];
    }];

4.迴圈動畫:我們在動畫代理事件的- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag中呼叫動畫開始的函式,這樣在動畫結束的時候就會自動的呼叫動畫進行迴圈播放

    - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{
    [self rotationAnimation];
        }

4.毛玻璃效果的新增

利用系統自帶的UIVisualEffectView類來建立毛玻璃效果,並設定為self.bouns來覆蓋整個檢視,詳細關於UIVisualEffectView的介紹請看《最近開發遇到的一些UI問題》

    UIVisualEffectView *bgView = [[UIVisualEffectView alloc] initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleLight]];
    bgView.alpha = 0.9f;
    bgView.frame = CGRectMake(0, 0, WIDTH, HEIGHT);
    bgView.layer.cornerRadius = BALL_RADIUS / 2;
    bgView.clipsToBounds = YES;
    [self addSubview:bgView];

5.後記

最近在從OC轉為Swift,自己也遇到了一些基於Swift很不錯的動畫,希望在學完Swift後能轉為OC,並和大家分享這個過程。學習動畫中遇到了很多問題,有幾何學上和物理上的問題,奈何高中數學老師死得早,幾何部分理解起來常常比較吃力,無奈自己愛折騰,希望能有更大的突破。



文/鄭欽洪_(簡書作者)
原文連結:http://www.jianshu.com/p/447b0de110a7
著作權歸作者所有,轉載請聯絡作者獲得授權,並標註“簡書作者”。

相關推薦

iOS旋轉載入動畫實現

1.前言 近日一直在看KITTEN寫的《A GUIDE TO IOS ANIMATION》,此乃iOS動畫開發的聖經,簡直手不釋卷。其中有一個動畫是載入動畫,因為文中沒有給出實現的解析,我在這裡解析一下動畫的實現原理,和自己加入一些新的東西。Github地址 git1.gi

使用Animation list實現網路請求過程載入動畫dialog

效果圖 實現過程主要是藉助於AnimationList實現幀動畫 animation_list.xml檔案 <?xml version="1.0" encoding="utf-8"?

CSS3的3D動畫實現(鐘擺、魔方)--實現代碼

等待 比例 需要 時間 span bottom translate abs ase CSS3中的3D動畫實現(鐘擺、魔方) CSS3的2D變形----傳統的transform變形效果 transform : translate、scale、rotate、skew… tran

iOSViewController載入View的幾種方式

ViewController 載入 View 的方式有: 建立 ViewController 的同時載入 View,此種方式可分別通過載入關聯1了 VC 的 xib,或純程式碼建立實現。相關的呼叫方法有: init 載入關聯了 VC 的 xib,或者純

iOS自定義View實現layoutSubviews佈局子控制元件

iOS開發中,- (void)layoutSubviews{}方法及相關方法注意點!! ==== ```objectivec - (void)creatAutoLayoutUSE { // 一、layout相關方法 } ``` - (void)layoutSubviews

iOS訊息轉發的實現

   嗯,執行時,執行時是個好東西。在Objective-C語言中,這個特性可以幫助我們幹很多的事情。    首先這個特性是把程式碼的決策從編譯和連結時變成執行的時候,這樣我們就可以用這個特性來做一些只有在執行的時候才能做到的東西,具體包括:    1.swizzling

ios播放gif動畫

轉自:http://blog.csdn.net/lovenjoe/article/details/7487142 iPhone SDK提供了多種動畫手段,UIView、UIImageView和CALayer都支援動畫。但如何處理常見的gif動畫呢?UIWebView提供了

iOS如何正確的實現行間距與行高

最近準備給 VirtualView-iOS 的文字元素新增一個 lineHeight 屬性,以便和 VirtualView-Android 配合時能更精確的保證雙平臺的一致性。面向 Google 以及 Stack Overflow 程式設計了一會後發現,能查到的資料大部分是介

unity基礎開發----unity的UV動畫實現程式碼

在unity有時候需要使用UV動畫,程式碼如下using UnityEngine; using System.Collections; public class UVAnimation : MonoBehaviour { public int ScrollSpe

iOS之TableViewCell載入動畫

1、 新增代理方法 -(void)tableView:(UITableView )tableView willDisplayCell:(UITableViewCell )cell forRowAtIndexPath:(NSIndexPath *)inde

iOS@功能的完整實現

點選上方“iOS開發”,選擇“置頂公眾號”關鍵時刻,第一時間送達!哼哼想不到吧,我又回來啦!好久

實用CSS3實現旋轉載入動畫

<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Document</title><style type="t

IOS 利用UIImageView實現載入動畫

前言:利用UIImageView實現載入動畫 大致步驟: 1、新增資料來源; 2、例項化圖片物件; 3、設定動畫圖片陣列; 4、設定圖片播放一次所需要的時長; 5、設定圖片播放次數 6、執行動畫; 具

iOS開發 ----- 載入動畫之牛頓擺的實現

牛頓擺動畫 自己看動畫有一段時間了,但是還是不是很能理解其中的一些屬性方法之類的東西,琢磨了一下午寫了一個牛頓擺的動畫,這裡記錄一下,一遍以後檢視先上圖 先說下思路 說下牛頓擺的大致運動過程 根據牛頓擺的原理,中間是不動得,只有兩邊

安卓自定義控制元件-實現IOS版UC瀏覽器三點載入動畫效果

1.實現分析 廢話不多說,看下IOS版UC瀏覽器的載入效果 簡單畫個圖看下整個過程 1.B圓的圓心移動的座標為:A圓和B圓的圓心的距離L的中點為圓心O1的下半圓的運動軌跡經過的座標,就有一個由B位置到A位置圓周運動的軌跡。 2.C圓的圓心

ios開發在cell上實現內容的動畫滑動效果

1、使用UITableView顯示內容,應熟悉datasource 以及delegate設定以及方法的使用。 2、自定義cell寫法,可以使用storyBoard以及xib來進行實現自定義的方法來實現相關的內容。 3、父子檢視控制器之間的切換方法,有什麼?pressent、

iOSiOS平移旋轉動畫 通過核心動畫實現動畫組)

有時需要對某個特定的View進行平移+旋轉的操作,其實很簡單,只需要一個動畫組就可以解決: #pragma mark 動畫 - (void)tipAnimation:(UIView *)tipView toPoint:(CGPoint)toPoint angle:(CGFl

[iOS]怎樣在iOS開發切換顯示語言實現國際化

art out title oca standard 文件 creat mit 工具類 1.在Project設置,加入中英兩種語言:2.新建Localizable.strings文件,作為多語言相應的詞典,存儲多種語言,點擊右側Localization,勾選中英:3.加入

網頁頁面預載入動畫實現載入後隱藏

我們做web app的時候,可以做一個頁面載入廣告,在你網頁載入的時候,先出現一段gif動圖或者是海報。 下面是實現頁面載入動畫的程式碼 首先js程式碼的實現 (function($){ $(window).load(function(){ $('#b

iOSHTML與OC的互動實現

   近日,由於開發需求,涉及到書寫HTML與OC互動的問題。特此做了一番研究,學習到了一點,所以,也就當是做個簡單的筆記。希望可以對有需求的人有幫助,就像我自己學習的時候,總是要到處翻書,到處搜尋。把這些問題解決掉。     以下為正文內容: &