iOS 基礎動畫

iOS的動畫效果一直都很棒很,給人的感覺就是很炫酷很流暢,起到增強用戶體驗的作用。在APP開發中實現動畫效果有很多種方式,對于簡單的應用場景,我們可以使用UIKit提供的動畫來實現。

UIView動畫

UIView動畫實質上是對CoreAnimation的封裝,iOS4.0以后,增加了Block動畫塊,提供更簡潔的方式來實現動畫。

共有六個常見的Block動畫方法:
  • 1、最簡單的Block動畫,包含時間和動畫[UIView animateWithDuration:<#(NSTimeInterval)#> animations:<#^(void)animations#>];

  • 2、帶有動畫完成回調的Block動畫 [UIView animateWithDuration:<#(NSTimeInterval)#> animations:<#^(void)animations#> completion:<#^(BOOL finished)completion#>];

  • 3、可設置延遲時間和過渡效果的Block動畫 ``[UIView animateWithDuration:<#(NSTimeInterval)#> delay:<#(NSTimeInterval)#> options:<#(UIViewAnimationOptions)#> animations:<#^(void)animations#> completion:<#^(BOOL finished)completion#>]

  • 4、Spring動畫,iOS7.0后新增Spring動畫(iOS系統動畫大部分采用SpringAnimation,適用于所有可被添加動畫效果的屬性)[UIView animateWithDuration:<#(NSTimeInterval)#> delay:<#(NSTimeInterval)#> usingSpringWithDamping:<#(CGFloat)#> initialSpringVelocity:<#(CGFloat)#> options:<#(UIViewAnimationOptions)#> animations:<#^(void)animations#> completion:<#^(BOOL finished)completion#>]

  • 5、Keyframes動畫,iOS7.0后新增關鍵幀動畫,支持屬性關鍵幀,不支持路徑關鍵幀 [UIView animateKeyframesWithDuration:<#(NSTimeInterval)#> delay:<#(NSTimeInterval)#> options:<#(UIViewKeyframeAnimationOptions)#> animations:<#^(void)animations#> completion:<#^(BOOL finished)completion#>]

  • 6、轉場動畫

    • 從舊視圖轉到新視圖的動畫效果,在該動畫過程中,fromView會從父視圖中移除,并講toView添加到父視圖中,注意轉場動畫的作用對象是父視圖(過渡效果體現在父視圖上)[UIView transitionFromView:<#(nonnull UIView *)#> toView:<#(nonnull UIView *)#> duration:<#(NSTimeInterval)#> options:<#(UIViewAnimationOptions)#> completion:<#^(BOOL finished)completion#>]
  • 單個視圖的過渡效果 [UIView transitionWithView:<#(nonnull UIView *)#> duration:<#(NSTimeInterval)#> options:<#(UIViewAnimationOptions)#> animations:<#^(void)animations#> completion:<#^(BOOL finished)completion#>]

UIView動畫可以設置的動畫屬性有
  • 1、大小變化(frame)
  • 2、拉伸變化(bounds)
  • 3、中心位置變化(center)
  • 4、旋轉(transform)
  • 5、透明度(aipha)
  • 6、背景色(backgroundColor)

transform屬性作用:給我們的控件做一些形變,(平移,縮放,旋轉)
移動

// 平移
//每次移動都是相對于上次位置
 _redView.transform = CGAffineTransformTranslate(_redView.transform, 100, 0);
//每次移動都是相對于最開始的位置
 _redView.transform = CGAffineTransformMakeTranslation(200, 0);

縮放

// sx:寬度縮放的比例 sy:高度縮放的比例
//每次縮放都是相對于最初的大小
_redView.transform = CGAffineTransformMakeScale(0.5, 0.5);
//每次縮放都是相對于上次的大小
_redView.transform = CGAffineTransformScale(_redView.transform, 0.5, 0.5);

旋轉

// 每次旋轉都是相對于最初的角度
_redView.transform = CGAffineTransformMakeRotation(M_PI_4);
//每次旋轉都是相對于現在的角度
_redView.transform = CGAffineTransformRotate(_redView.transform, M_PI_4);

實戰說明

1、最簡潔的Block動畫:包含時間和動畫

代碼

[UIView animateWithDuration:3 animations:^{
        //執行動畫
        _MyView.transform = CGAffineTransformScale(_MyView.transform, 0.5, 0.5);//縮放
        _MyView.transform = CGAffineTransformRotate(_MyView.transform, M_PI_4);//旋轉
        _MyView.transform = CGAffineTransformTranslate(_MyView.transform, 200, 100);//平移
    }];

效果圖

animation1.gif
2、可設置延遲時間和過渡效果的Block動畫

代碼

[UIView animateWithDuration:3 delay:1 options:UIViewAnimationOptionTransitionCurlDown animations:^{
        //執行動畫
        _MyView.transform = CGAffineTransformScale(_MyView.transform, 0.5, 0.5);//縮放
        _MyView.transform = CGAffineTransformRotate(_MyView.transform, M_PI_4);//旋轉
        _MyView.transform = CGAffineTransformTranslate(_MyView.transform, 200, 100);//平移
        
    } completion:^(BOOL finished) {
        NSLog(@"動畫完成的回調");
    }];

UIViewAnimationOptions的枚舉值如下,可組合使用

UIViewAnimationOptionLayoutSubviews//進行動畫時布局子控件
UIViewAnimationOptionAllowUserInteraction//進行動畫時允許用戶交互
UIViewAnimationOptionBeginFromCurrentState//從當前狀態開始動畫
UIViewAnimationOptionRepeat//無限重復執行動畫
UIViewAnimationOptionAutoreverse//執行動畫回路
UIViewAnimationOptionOverrideInheritedDuration//忽略嵌套動畫的執行時間設置
UIViewAnimationOptionOverrideInheritedCurve//忽略嵌套動畫的曲線設置
UIViewAnimationOptionAllowAnimatedContent//轉場:進行動畫時重繪視圖
UIViewAnimationOptionShowHideTransitionViews//轉場:移除(添加和移除圖層的)動畫效果
UIViewAnimationOptionOverrideInheritedOptions//不繼承父動畫設置
UIViewAnimationOptionCurveEaseInOut//時間曲線,慢進慢出(默認值)
UIViewAnimationOptionCurveEaseIn//時間曲線,慢進
UIViewAnimationOptionCurveEaseOut//時間曲線,慢出
UIViewAnimationOptionCurveLinear//時間曲線,勻速
UIViewAnimationOptionTransitionNone//轉場,不使用動畫
UIViewAnimationOptionTransitionFlipFromLeft//轉場,從左向右旋轉翻頁
UIViewAnimationOptionTransitionFlipFromRight//轉場,從右向左旋轉翻頁
UIViewAnimationOptionTransitionCurlUp//轉場,下往上卷曲翻頁
UIViewAnimationOptionTransitionCurlDown//轉場,從上往下卷曲翻頁
UIViewAnimationOptionTransitionCrossDissolve//轉場,交叉消失和出現
UIViewAnimationOptionTransitionFlipFromTop//轉場,從上向下旋轉翻頁
UIViewAnimationOptionTransitionFlipFromBottom//轉場,從下向上旋轉翻頁

3、Spring動畫

usingSpringWithDamping:震動效果,范圍0~1,數值越小震動效果越明顯
initialSpringVelocity:初始速度,數值越大初始速度越快

 [UIView animateWithDuration:3 delay:0 usingSpringWithDamping:0.1 initialSpringVelocity:100 options:UIViewAnimationOptionRepeat animations:^{
        //執行動畫
        _MyView.transform = CGAffineTransformScale(_MyView.transform, 0.5, 0.5);//縮放
        _MyView.transform = CGAffineTransformRotate(_MyView.transform, M_PI_4);//旋轉
        _MyView.transform = CGAffineTransformTranslate(_MyView.transform, 200, 100);//平移

    } completion:^(BOOL finished) {
        
    }];

效果圖

animation2.gif
4、Keyframes動畫

iOS7.0后新增關鍵幀動畫,支持屬性關鍵幀,不支持路徑關鍵幀
options:動畫的過渡效果

[UIView animateKeyframesWithDuration:0.5 delay:0 options:UIViewKeyframeAnimationOptionCalculationModeCubicPaced animations:^{
        _MyView.backgroundColor = [UIColor blueColor];
    } completion:nil];
    
    [UIView animateKeyframesWithDuration:1 delay:0 options:UIViewKeyframeAnimationOptionCalculationModeCubicPaced animations:^{
        _MyView.backgroundColor = [UIColor grayColor];
    } completion:nil];
    
    [UIView animateKeyframesWithDuration:1.5 delay:0 options:UIViewKeyframeAnimationOptionCalculationModeCubicPaced animations:^{
        _MyView.backgroundColor = [UIColor greenColor];
    } completion:nil];
    
    [UIView animateKeyframesWithDuration:2 delay:0 options:UIViewKeyframeAnimationOptionCalculationModeCubicPaced animations:^{
        _MyView.backgroundColor = [UIColor redColor];
    } completion:nil];

UIViewKeyframeAnimationOptions的枚舉值如下,可組合使用:

UIViewAnimationOptionLayoutSubviews//進行動畫時布局子控件
UIViewAnimationOptionAllowUserInteraction//進行動畫時允許用戶交互
UIViewAnimationOptionBeginFromCurrentState//從當前狀態開始動畫
UIViewAnimationOptionRepeat//無限重復執行動畫
UIViewAnimationOptionAutoreverse//執行動畫回路
UIViewAnimationOptionOverrideInheritedDuration//忽略嵌套動畫的執行時間設置
UIViewAnimationOptionOverrideInheritedOptions//不繼承父動畫設置
UIViewKeyframeAnimationOptionCalculationModeLinear//運算模式:連續
UIViewKeyframeAnimationOptionCalculationModeDiscrete//運算模式:離散
UIViewKeyframeAnimationOptionCalculationModePaced//運算模式:均勻執行
UIViewKeyframeAnimationOptionCalculationModeCubic//運算模式:平滑
UIViewKeyframeAnimationOptionCalculationModeCubicPaced//運算模式:平滑均勻

效果圖

animation3.gif
5、轉場動畫
單個視圖的過渡效果

代碼

[UIView transitionWithView:_MyView duration:1 options:UIViewAnimationOptionOverrideInheritedCurve animations:^{
        _MyView.backgroundColor = [UIColor greenColor];
    } completion:nil];

效果圖

animation4.gif
從舊視圖轉到新視圖的動畫效果
[UIView transitionFromView:_MyView toView:_view duration:1 options:UIViewAnimationOptionTransitionFlipFromTop completion:nil];

CAAnimation核心動畫

在iOS的不同圖形層次中都可以寫動畫代碼。越上層,封裝程度越高,動畫實現越簡潔越簡單,但是自由度越低;反之亦然。
如果想要做出更炫的動畫,就必須要了解CAAnimation核心動畫了。

Core Animation結構
1053533-6eae72f7fd9bd271.png
屏幕快照 2017-04-20 下午9.56.37.png

基礎動畫(CABasicAnimation)

基礎動畫(CABasicAnimation),通過設定起始點,終點,時間,動畫會沿著你這設定點進行移動。可以看做特殊的CAKeyFrameAnimation

開始之前我們需要先了解一個概念:CALayer

CALayer是個與UIView很類似的概念,同樣有backgroundColor、frame等相似的屬性,我們可以將UIView看做一種特殊的CALayer。但實際上UIView是對CALayer封裝,在CALayer的基礎上再添加交互功能。UIView的顯示必須依賴于CALayer。
我們同樣可以跟新建view一樣新建一個layer,然后添加到某個已有的layer上,同樣可以對layer調整大小、位置、透明度等。
一般來說,layer可以有兩種用途:一是對view相關屬性的設置,包括圓角、陰影、邊框等參數,更詳細的參數請點擊這里;二是實現對view的動畫操控。因此對一個view進行動畫,本質上是對該view的.layer進行動畫操縱。

注意點1:KeyPath中key值的設置

實例化方法

 //圍繞y軸旋轉
CABasicAnimation *transformAnima = [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"];

使用方法animationWithKeyPath:CABasicAnimation進行實例化,并指定Layer的屬性作為關鍵路徑進行注冊。
keyPath決定了基礎動畫的類型,該值不能隨便取,一旦取錯就達不到想要的效果。要改變位置就取position,要改變透明度就取opacity,要等比例縮放就取transform.scale...
一些常用的animationWithKeyPath值的總結

3D62A8E2-94E2-4FC3-AE05-A71296F4B324.png
注意點2:fillMode屬性的理解

該屬性定義了你的動畫在開始和結束時的動作。默認值是 kCAFillModeRemoved
fillMode的作用就是決定當前對象過了非active時間段的行為. 非active時間段是指動畫開始之前以及動畫結束之后。如果是一個動畫CAAnimation,則需要將其removedOnCompletion設置為NO,要不然fillMode不起作用.

kCAFillModeRemoved 這個是默認值,也就是說當動畫開始前和動畫結束后,動畫對layer都沒有影響,動畫結束后,layer會恢復到之前的狀態
kCAFillModeForwards 當動畫結束后,layer會一直保持著動畫最后的狀態
kCAFillModeBackwards這個和kCAFillModeForwards是相對的,就是在動畫開始前,你只要將動畫加入了一個layer,layer便立即進入動畫的初始狀態。因為有可能出現fromValue不是目前layer的初始狀態的情況,如果fromValue就是layer當前的狀態,則這個參數就沒太大意義。
kCAFillModeBoth理解了上面兩個,這個就很好理解了,這個其實就是上面兩個的合成.動畫加入后開始之前,layer便處于動畫初始狀態,動畫結束后layer保持動畫最后的狀態.

注意點3

[self.view.layer addAnimation:positionAnima forKey:@"AnimationMoveY"];我們可以根據這個Key找到這個layer

注意點4:一些常用的屬性
7E7672C6-9B0E-4743-9533-C3B506329F1D.png
我們做一個心跳的效果

代碼

//初始化CALayer
    CALayer *layer = [[CALayer alloc]init];
    layer.backgroundColor = [UIColor redColor].CGColor;
    layer.frame = CGRectMake(100, 100, 100, 100);
    layer.cornerRadius = 10;
    [self.view.layer addSublayer:layer];
    //配置CABasicAnimation
    CABasicAnimation *basicAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
    basicAnimation.fromValue = [NSNumber numberWithFloat:1.0];
    basicAnimation.toValue = [NSNumber numberWithFloat:1.5];
    //當動畫執行到toValue指定的狀態時是從toValue的狀態逆回去,還是直接跳到fromValue的狀態再執行一遍
    basicAnimation.autoreverses = YES;
    basicAnimation.removedOnCompletion = NO;
    basicAnimation.duration = 0.5;
    basicAnimation.repeatCount = MAXFLOAT;
    //把動畫內容添加到layer上
    [layer addAnimation:basicAnimation forKey:@"basicAnimation"];
basicAnimation.gif

關鍵幀動畫(CAKeyFrameAnimation)

CABasicAnimation只能從一個數值(fromValue)變到另一個數值(toValue),而CAKeyframeAnimation會使用一個NSArray保存這些數值

屬性介紹

  • values:就是上述的NSArray對象。里面的元素稱為”關鍵幀”(keyframe)。動畫對象會在指定的時間(duration)內,依次顯示values數組中的每一個關鍵幀

  • path:可以設置一個CGPathRef\CGMutablePathRef,讓層跟著路徑移動。path只對CALayer的anchorPoint和position起作用。如果你設置了path,那么values將被忽略

  • keyTimes:可以為對應的關鍵幀指定對應的時間點,其取值范圍為0到1.0,keyTimes中的每一個時間值都對應values中的每一幀.當keyTimes沒有設置的時候,各個關鍵幀的時間是平分的

value方式代碼

 //創建動畫對象
    CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    
    //設置value
    NSValue *value1=[NSValue valueWithCGPoint:CGPointMake(100, 100)];
    NSValue *value2=[NSValue valueWithCGPoint:CGPointMake(200, 100)];
    NSValue *value3=[NSValue valueWithCGPoint:CGPointMake(200, 200)];
    NSValue *value4=[NSValue valueWithCGPoint:CGPointMake(100, 200)];
    NSValue *value5=[NSValue valueWithCGPoint:CGPointMake(100, 300)];
    NSValue *value6=[NSValue valueWithCGPoint:CGPointMake(200, 400)];
    
    
    animation.values=@[value1,value2,value3,value4,value5,value6];
    
    //重復次數 默認為1
    animation.repeatCount=MAXFLOAT;
    //設置是否原路返回默認為不
    animation.autoreverses = YES;
    //設置移動速度,越小越快
    animation.duration = 4.0f;
    animation.removedOnCompletion = NO;
    animation.fillMode = kCAFillModeForwards;
    
    //給這個view加上動畫效果
    [_keyFrameView.layer addAnimation:animation forKey:nil];
    
KeyFrameValue.gif

path方法代碼

CAKeyframeAnimation *anima = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    
    UIBezierPath *path = [UIBezierPath bezierPath];
    [path moveToPoint:CGPointMake(100, 100)];
    [path addLineToPoint:CGPointMake(150, 150)];
    [path addLineToPoint:CGPointMake(100, 200)];
    [path addLineToPoint:CGPointMake(50, 150)];

    anima.path = path.CGPath;
    anima.duration = 2.0f;
    anima.repeatCount= MAXFLOAT;
    anima.autoreverses = NO;
    anima.removedOnCompletion = NO;
    anima.fillMode = kCAFillModeForwards;
    
    
    [_keyFrameView.layer addAnimation:anima forKey:@"pathAnimation"];
KeyFramePath.gif

動畫組動畫(CAAnimationGroup)

動畫組(CAAnimationGroup)是核心動畫中又一個比較重要的知識點。動畫組顧名思義就是一組動畫,它可以將多個動畫對象保存起來,然后再將其添加到layer上,讓組中所有的動畫對象同時并發執行。

 /****************** 創建平移動畫 ******************/
    CABasicAnimation *basicAnim = [CABasicAnimation animation];
    // 設置動畫屬性
    basicAnim.keyPath = @"position.y";
    basicAnim.toValue = @350;
    
    /****************** 創建縮放動畫 ******************/
    CABasicAnimation *scaleAnim = [CABasicAnimation animation];
    // 設置動畫屬性
    scaleAnim.keyPath = @"transform.scale";
    scaleAnim.toValue = @0.5;
    
   ;
    
    /****************** 創建動畫組 ******************/
    CAAnimationGroup *groupAnim = [CAAnimationGroup animation];
    // 將動畫對象都添加到CAAnimationGroup對象中
    groupAnim.animations = @[basicAnim, scaleAnim];
    
    /****************** 通過動畫組對象統一設置動畫屬性和狀態 ******************/
    // 設置動畫的執行時長
    groupAnim.duration = 0.5;
    // 動畫完成時保持在最新的狀態
    groupAnim.removedOnCompletion = NO;
    groupAnim.fillMode = kCAFillModeForwards;
    
    
    groupAnim.duration = 2.0f;
    groupAnim.repeatCount= MAXFLOAT;
    groupAnim.autoreverses = YES;
    groupAnim.removedOnCompletion = NO;
    groupAnim.fillMode = kCAFillModeForwards;

    /****************** 將動畫組對象添加到redView的layer上 ******************/
    [_animationGroupView.layer addAnimation:groupAnim forKey:nil];

animationGroup.gif

轉場動畫(CATranstion)

CATransition是CAAnimation的子類,用于做轉場動畫,能夠為層提供移出屏幕和移入屏幕的動畫效果。iOS比Mac OS X的轉場動畫效果少一點
UINavigationController就是通過CATransition實現了將控制器的視圖推入屏幕的動畫效果
動畫屬性:
type:動畫過渡類型
subtype:動畫過渡方向
startProgress:動畫起點(在整體動畫的百分比)
endProgress:動畫終點(在整體動畫的百分比)

轉場動畫過渡效果
屏幕快照 2016-05-25 20.41.32.png
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容