iOS那些簡單的動畫(不定期更新)

關于 Core Animation

Core Animation是一組非常強大的動畫處理API,使用它能做出很多優雅的動畫效果。能用的動畫類有4個子類:CABasicAnimation、CAKeyframeAnimation、CATransition、CAAnimationGroup

開發步驟:

  1. 初始化一個動畫對象(CAAnimation)并設置一些動畫相關屬性.
  1. 添加動畫對象到層(CALayer)中,開始執行動畫.

CALayer中很多屬性都可以通過CAAnimation實現動畫效果, 包括opacity, position, transform, bounds, contents等,具體可以在API文檔中查找

通過調用CALayer的addAnimation:forKey:增加動畫到層(CALayer)中,這樣就能觸發動畫了.通過調用removeAnimationForKey:可以停止層中的動畫.

注:Core Animation的動畫執行過程都是在后臺操作的,不會阻塞主線程.

創建動畫時你可能用到的屬性

屬性 | 解讀
----|------|----
Autoreverses | 設定這個屬性為 YES 時,在它到達目的地之后,動畫的返回到開始的值,代替了直接跳轉到開始的值,過渡平滑
Duration |設定開始值到結束值花費的時間。期間會被速度的屬性所影響
RemovedOnCompletion | 這個屬性默認為 YES,在指定的時間段完成后,動畫就自動的從層上移除了。
FillMode | 這個屬性一般和 RemovedOnCompletion 配合使用,保持動畫狀態。其中kCAFillModeForwards 當動畫結束后,layer會一直保持著動畫最后的狀態.此時將RemovedOnCompletion設為NO
Speed | 默認的值為 1.0.如果你改變這個值為 2.0,動畫會用 2 倍的速度播放。這樣的影響就是使持續時間減半。如果你指定的持續時間為 6 秒,速度為 2.0,動畫就會播放 3 秒鐘即一半的持續時間。
RepeatCount | 默認的是 0,動畫只會播放一次。如果指定一個無限大的重復次數,使用 MAXFLOAT 。這個不應該和 repeatDration 屬性一塊使用
RepeatDuration | 這個屬性指定了動畫應該被重復多久。動畫會一直重復,直到設定的時間用完。同上它不應該和 repeatCount 一起使用
FromValue | 設置動畫的初始值
ToValue | 設置動畫的到達值
TimingFunction | 控制動畫運行的節奏. kCAMediaTimingFunctionLinear(線性):勻速,給你一個相對靜態的感覺 kCAMediaTimingFunctionEaseIn(漸進):動畫緩慢進入,然后加速離開 kCAMediaTimingFunctionEaseOut(漸出):動畫全速進入,然后減速的到達目的地 kCAMediaTimingFunctionEaseInEaseOut(漸進漸出):動畫緩慢的進入,中間加速,然后減速的到達目的地。這個是默認的動畫行為。
BeginTime | 可以用來設置動畫延遲執行時間,若想延遲1s,就設置為CACurrentMediaTime()+1,CACurrentMediaTime()為圖層的當前時間

巧妙的運用這些可以屬性實現很棒的動畫效果,比如下面:用CABasicAnimation實現的動畫

CABasicAnimation動畫

簡單的呼吸和搖擺動畫


animation.gif

簡單的代碼

 1.呼吸動畫
    CABasicAnimation *animation =[CABasicAnimation animationWithKeyPath:@"opacity"];
    animation.fromValue = [NSNumber numberWithFloat:1.0f];
    animation.toValue = [NSNumber numberWithFloat:0.0f];
    animation.autoreverses = YES;    //回退動畫(動畫可逆,即循環)
    animation.duration = 1.0f;
    animation.repeatCount = MAXFLOAT;
    animation.removedOnCompletion = NO;
    animation.fillMode = kCAFillModeForwards;//removedOnCompletion,fillMode配合使用保持動畫完成效果
    animation.timingFunction=[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
    [self.alphaTagButton.layer addAnimation:animation forKey:@"aAlpha"];  

2.搖擺動畫
    //設置旋轉原點
    self.sharkTagButton.layer.anchorPoint = CGPointMake(0.5, 0);
    CABasicAnimation* rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
    //角度轉弧度(這里用1,-1簡單處理一下)
    rotationAnimation.toValue = [NSNumber numberWithFloat:1];
    rotationAnimation.fromValue = [NSNumber numberWithFloat:-1];
    rotationAnimation.duration = 1.0f;
    rotationAnimation.repeatCount = MAXFLOAT;
    rotationAnimation.removedOnCompletion = NO;
    rotationAnimation.autoreverses = YES;
    rotationAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    rotationAnimation.fillMode = kCAFillModeForwards;
    [self.sharkTagButton.layer addAnimation:rotationAnimation forKey:@"revItUpAnimation"];
    

陀螺儀&加速儀的動畫

ps:好吧 這個屬于亂入,和上面的搖擺動畫差不多的效果,只是這個是手動的 哈哈

3、陀螺儀&加速儀的動畫
    self.motionManager = [[CMMotionManager alloc] init];
    self.motionManager.deviceMotionUpdateInterval = 1.0f/100.0f; //1秒100次
    self.sharkTagButton.layer.anchorPoint = CGPointMake(0.5, 0);
    [self.motionManager startDeviceMotionUpdatesToQueue:[NSOperationQueue currentQueue] withHandler:^(CMDeviceMotion *motion, NSError *error) {
        if(fabs(motion.attitude.roll)<1.0f)
        {
            [UIView animateWithDuration:0.6 animations:^{
                self.sharkTagButton.layer.transform = CATransform3DMakeRotation(-(motion.attitude.roll), 0, 0, 1);
            }];
        }else if (fabs(motion.attitude.roll)<1.5f)
        {
            [UIView animateWithDuration:0.6 animations:^{
                int s;
                if (motion.attitude.roll>0)
                {
                    s=-1;
                }else
                {
                    s = 1;
                }
                self.sharkTagButton.layer.transform = CATransform3DMakeRotation(s*M_PI_2, 0, 0, 1);
            }];
        }
        if ((motion.attitude.pitch)<0)
        {
            [UIView animateWithDuration:0.6 animations:^{
                self.sharkTagButton.layer.transform = CATransform3DMakeRotation(M_PI, 0, 0, 1);
            }];
        }
        
    }];

Demo地址:
https://github.com/yongliangP/CABasicAnimationDemo



CATransition之簡單的轉場動畫

CAAnimation的子類,用于做轉場動畫,能夠為層提供移出屏幕和移入屏幕的動畫效果。

屬性 解讀
type 動畫過渡類型
subtype 動畫過渡方向
  • 常用動畫類型:
type的值 解讀 對應常量
fade 淡入淡出 kCATransitionFade
push 推擠 kCATransitionPush
reveal 揭開 kCATransitionReveal
moveIn 覆蓋 kCATransitionMoveIn
cube 立方體 私有API
suckEffect 吮吸 私有API
oglFlip 翻轉 私有API
rippleEffect 波紋 私有API
pageCurl 反翻頁 私有API
cameraIrisHollowOpen 開鏡頭 私有API
cameraIrisHollowClose 關鏡頭 私有API

注:私有API只能通過字符串使用哈


  • 過渡方向參數:
subtype的值 解讀
kCATransitionFromRight 從右轉場
kCATransitionFromLeft 從左轉場
kCATransitionFromBottom 從下轉場
kCATransitionFromTop 從上轉場

簡單的CATransition動畫


CATransitionDemo2.gif
-(void)animationWithType:(NSString*)type
{

    //- 創建一個轉場動畫:
    CATransition *transition = [CATransition animation];
    transition.repeatCount = 5;

    //    - 確定動畫類型:
    transition.type = type;
    
    //    - 確定子類型(方向等)
    transition.subtype = kCATransitionFromLeft;
    
    //    - 確定動畫時間
    transition.duration = 1;
    
    //    - 添加動畫
    [self.imageView.layer addAnimation:transition forKey:nil];
    
}

使用時只用傳你的想要的動畫類型就好,私有API只能通過字符串使用哈。

[self animationWithType:self.dataArray[indexPath.row]];

DEMO地址:https://github.com/yongliangP/CATransitionDemo


---20160908更新


CAKeyframeAnimation

先看圖,就是那個在跑的小圓球,為了方便,把動畫集成在了一個Demo里了

ScreenShotDemo2.gif
  • 1 .簡單介紹

CAKeyframeAnimation是CApropertyAnimation的子類,跟CABasicAnimation的區別是:CABasicAnimation只能從一個數值(fromValue)變到另一個數值(toValue),而CAKeyframeAnimation會使用一個NSArray保存這些數值,是一種更靈活的動畫方式。

  • 2 .屬性介紹
屬性 解讀
values NSArray對象,里面的元素稱為”關鍵幀”(keyframe)。動畫對象會在指定的時間(duration)內,依次顯示values數組中的每一個關鍵幀
path 可以設置一個CGPathRef\CGMutablePathRef,讓層跟著路徑移動。path只對CALayer的anchorPoint和position起作用。如果你設置了path,那么values將被忽略
keyTimes 可以為對應的關鍵幀指定對應的時間點,其取值范圍為[0,1],keyTimes中的每一個時間值都對應values中的每一幀.當keyTimes沒有設置的時候,各個關鍵幀的時間是平分的
  • 3 .實現
  • 3.1 values方式實現
-(void)setUpCAKeyframeAnimationUseValues
{

    CAKeyframeAnimation *animation = [CAKeyframeAnimation animation];
    
    animation.keyPath = @"position";
    
    NSValue *value1 = [NSValue valueWithCGPoint:CGPointMake(50, 50)];
    
    NSValue *value2 = [NSValue valueWithCGPoint:CGPointMake(kWindowWidth - 50, 50)];
    
    NSValue *value3 = [NSValue valueWithCGPoint:CGPointMake(kWindowWidth - 50, kWindowHeight-50)];
    
    NSValue *value4 = [NSValue valueWithCGPoint:CGPointMake(50, kWindowHeight-50)];
    
    NSValue *value5 = [NSValue valueWithCGPoint:CGPointMake(50, 50)];
    
    animation.values = @[value1,value2,value3,value4,value5];
    animation.repeatCount = MAXFLOAT;
    
    animation.removedOnCompletion = NO;
    
    animation.fillMode = kCAFillModeForwards;
    
    animation.duration = 6.0f;
    
    animation.timingFunction=[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    
    [self.keyButton.layer addAnimation:animation forKey:@"values"];
    
}

    • 3.2 path方式實現
-(void)setUpCAKeyframeAnimationUsePath
{
    CAKeyframeAnimation *animation = [CAKeyframeAnimation animation];
    
    animation.keyPath = @"position";
    
    CGMutablePathRef path = CGPathCreateMutable();
    
    //矩形線路
    CGPathAddRect(path, NULL, CGRectMake(50,50, kWindowWidth - 100,kWindowHeight - 100));
    
    animation.path=path;
    
    CGPathRelease(path);
    
    animation.repeatCount = MAXFLOAT;
    
    animation.removedOnCompletion = NO;
    
    animation.fillMode = kCAFillModeForwards;
    
    animation.duration = 10.0f;
    
    animation.timingFunction=[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    
    [self.keyButton.layer addAnimation:animation forKey:@"path"];


}

    • 3.3 keyTimes演示
-(void)setUpCAKeyframeAnimationUsekeyTimes
{
    
    CAKeyframeAnimation *animation = [CAKeyframeAnimation animation];
//    animation.keyPath = @"transform.translation.x";
    animation.keyPath = @"position.x";
    animation.values = @[@0, @20, @-20, @20, @0];
    animation.keyTimes = @[ @0, @(1 / 6.0), @(3 / 6.0), @(5 / 6.0), @1 ];
    animation.duration = 0.5;
    animation.additive = YES;
    [self.sharkTagButton.layer addAnimation:animation forKey:@"keyTimes"];

}


---20160921更新


CAAnimationGroup

看圖,就是那個下方的小長方形,簡單實現

ScreenShotGroupDemo.gif

動畫組,顧名思義就是動畫的組合,具體動畫可以參考上文,不同的腦洞會出現不同的化學反應。

簡單示例:

    CABasicAnimation * animationScale = [CABasicAnimation animation];
    animationScale.keyPath = @"transform.scale";
    animationScale.toValue = @(0.1);
    
    CABasicAnimation *animationRota = [CABasicAnimation animation];
    animationRota.keyPath = @"transform.rotation";
    animationRota.toValue = @(M_PI_2);
    
    CAAnimationGroup * group = [[CAAnimationGroup alloc] init];
    group.duration = 3.0;
    group.fillMode = kCAFillModeForwards;
    group.removedOnCompletion = NO;
    group.repeatCount = MAXFLOAT;
    
    group.animations = @[animationScale,animationRota];
    [self.groupButton.layer addAnimation:group forKey:nil];
 

Demo傳送門

附:關于keyPath你可能用到的屬性

屬性 解讀
transform.rotation.x 圍繞x軸翻轉。y,z同理 參數:角度
transform.rotation 默認圍繞z軸
transform.scale.x x方向縮放。y,z同理
transform.scale 所有方向縮放
transform.translation.x x軸方向移動,參數:x軸上的坐標。y,z同理
transform.translation 移動到的點
zPosition 平面的位置
opacity 透明度
backgroundColor 背景顏色 參數:顏色 (id)[[UIColor redColor] CGColor]
cornerRadius layer圓角
borderWidth 邊框寬度
bounds 大小 參數:CGRect
contents 內容 參數:CGImage
contentsRect 可視內容 參數:CGRect 值是0~1之間的小數
position 位置,效果和transform.rotation差不多
shadowColor 陰影顏色
shadowOffset 陰影偏移
shadowOpacity 陰影透明度
shadowRadius 陰影角度

照例放Demo
Demo地址:
https://github.com/yongliangP/CABasicAnimationDemo
如果你覺得對你有幫助請點喜歡哦,也可以關注我,每周至少一篇技術。
或者關注 我的專題 每周至少5篇更新,多謝支持哈。
(ps:核心動畫編程pdf中文版想要的可以私信我)

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,505評論 6 533
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,556評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,463評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,009評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,778評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,218評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,281評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,436評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,969評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,795評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,993評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,537評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,229評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,659評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,917評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,687評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,990評論 2 374

推薦閱讀更多精彩內容