iOS 動畫使用總結

前言

之前要作動畫方面相關的功能時都是去百度,想着本身也總結下,方便本身記憶和查找,更加深本身對這方面的理解ios

iOS 圖形分層

img

平常開發 UIKIt 層和 Core Animation 層的動畫基本能夠實現絕大多數需求,而且層級越高 API 的封裝程度越高,也越簡潔。本文主要講解 View Animation 和 Core Animation。git

UIKit 層

UIView Animation

咱們來看看經過 UIView Animation 均可以實現那些動畫spring

img

大小動畫(frame改變)

#pragma mark  ---------------------大小動畫,frame 改變
- (void)initSizeAnimation {
    CGRect origin = self.showImage.frame;
    CGRect terminal = CGRectMake(SCREEN_W/2-100, SCREEN_H/2-100, 200, 200);
    [UIView animateWithDuration:1 animations:^{
        self.showImage.frame = terminal;
    } completion:^(BOOL finished) {
        [UIView animateWithDuration:1 animations:^{
            self.showImage.frame = origin;
        }];
    }];
}

拉伸動畫 bounds 改變

#pragma mark ------------------拉伸動畫 bounds 改變
- (void)initBoundsAnimation {
    CGRect origin = self.showImage.bounds;
    //拉伸動畫基於view的bound改變,只改變寬高,
    CGRect terminal = CGRectMake(0, 0, 200, 150);
    [UIView animateWithDuration:1 animations:^{
        self.showImage.bounds = terminal;
    } completion:^(BOOL finished) {
        [UIView animateWithDuration:1 animations:^{
            self.showImage.bounds = origin;
        }];
    }];
}

中心位置動畫,改變center

#pragma mark ----------------中心位置動畫,改變center
- (void)initCenterAnimation {
    CGPoint origin = self.showImage.center;
    CGPoint terminal = CGPointMake(self.showImage.center.x, self.showImage.center.y-100);
    [UIView animateWithDuration:1 animations:^{
        self.showImage.center = terminal;
    } completion:^(BOOL finished) {
        [UIView animateWithDuration:1 animations:^{
            self.showImage.center = origin;
        }];
    }];
}

旋轉動畫,改變transform

#pragma mark ----------------旋轉動畫,改變transform
- (void)initTransformAnimation {
    CGAffineTransform origin = self.showImage.transform;
    [UIView animateWithDuration:2 animations:^{
//        self.showImage.transform = CGAffineTransformMakeScale(0.6, 0.6);//縮放
//        self.showImage.transform = CGAffineTransformMakeTranslation(60, -60);//偏移
        self.showImage.transform = CGAffineTransformMakeRotation(4.0f);//旋轉
    } completion:^(BOOL finished) {
        [UIView animateWithDuration:2 animations:^{
            self.showImage.transform = origin;
        }];
    }];
}

透明度動畫 改變alpha

#pragma mark ----------------透明度動畫 改變alpha
- (void)initAlphaAnimation {
    [UIView animateWithDuration:2 animations:^{
        self.showImage.alpha = 0.3;
    } completion:^(BOOL finished) {
        [UIView animateWithDuration:2 animations:^{
            self.showImage.alpha = 1;
        }];
    }];
}

轉場動畫 transition

#pragma mark ----------------轉場動畫 transition
- (void)initTransitionAnimation {
    [UIView transitionWithView:self.showImage duration:2.0 options:UIViewAnimationOptionTransitionFlipFromTop animations:^{
        
    } completion:^(BOOL finished) {
        [UIView transitionWithView:self.showImage  duration:2  options:UIViewAnimationOptionTransitionFlipFromBottom animations:^{
            
        } completion:^(BOOL finished) {
            
        }];
    }];
}

spring 動畫(彈簧效果)(ios7以上)

#pragma mark ----------------spring 動畫(彈簧效果)
- (void)initSpringAnimation {
    CGRect origin = self.showImage.frame;
    CGRect terminal = CGRectMake(origin.origin.x+50, origin.origin.y, 150, 150);
    [UIView animateWithDuration:1 delay:0 usingSpringWithDamping:0.5 initialSpringVelocity:4 options:UIViewAnimationOptionCurveLinear animations:^{
        self.showImage.frame = terminal;
    } completion:^(BOOL finished) {
        [UIView animateWithDuration:1 delay:1 usingSpringWithDamping:0.5 initialSpringVelocity:4 options:UIViewAnimationOptionCurveLinear animations:^{
            self.showImage.frame = origin;
        } completion:^(BOOL finished) {
            
        }];
    }];
}

背景顏色動畫

#pragma mark ----------------背景顏色動畫 改變 background
- (void)initBackgroundAnimation {
    self.showImage.image = [UIImage imageNamed:@"example1"];
    
    [UIView animateKeyframesWithDuration:6.0 delay:0.f options:UIViewKeyframeAnimationOptionCalculationModeLinear animations:^{
        [UIView addKeyframeWithRelativeStartTime:0.f relativeDuration:1.0 / 4 animations:^{
            self.showImage.backgroundColor = [UIColor redColor];
        }];
        [UIView addKeyframeWithRelativeStartTime:1.0 / 4 relativeDuration:1.0 / 4 animations:^{
            self.showImage.backgroundColor = [UIColor greenColor];
        }];
        [UIView addKeyframeWithRelativeStartTime:2.0 / 4 relativeDuration:1.0 / 4 animations:^{
            self.showImage.backgroundColor = [UIColor yellowColor];
        }];
        [UIView addKeyframeWithRelativeStartTime:2.0 / 4 relativeDuration:1.0 / 4 animations:^{
            self.showImage.backgroundColor = [UIColor greenColor];
        }];
        [UIView addKeyframeWithRelativeStartTime:1.0 / 4 relativeDuration:1.0 / 4 animations:^{
            self.showImage.backgroundColor = [UIColor whiteColor];
        }];
    } 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  //轉場,從下向上旋轉翻頁

UIViewKeyframeAnimationOptions

UIViewAnimationOptionLayoutSubviews           //進行動畫時佈局子控件
UIViewAnimationOptionAllowUserInteraction     //進行動畫時容許用戶交互
UIViewAnimationOptionBeginFromCurrentState    //從當前狀態開始動畫
UIViewAnimationOptionRepeat                   //無限重複執行動畫
UIViewAnimationOptionAutoreverse              //執行動畫迴路
UIViewAnimationOptionOverrideInheritedDuration //忽略嵌套動畫的執行時間設置
UIViewAnimationOptionOverrideInheritedOptions //不繼承父動畫設置

UIViewKeyframeAnimationOptionCalculationModeLinear     //運算模式 :連續
UIViewKeyframeAnimationOptionCalculationModeDiscrete   //運算模式 :離散
UIViewKeyframeAnimationOptionCalculationModePaced      //運算模式 :均勻執行
UIViewKeyframeAnimationOptionCalculationModeCubic      //運算模式 :平滑
UIViewKeyframeAnimationOptionCalculationModeCubicPaced //運算模式 :平滑均勻

總結

  • UIView 動畫主要變化 UIView 自身的屬性
  • 一個效果有多種方式實現,經過組合也能夠實現比較高級的動畫效果

Core Animation

Core Animation是直接做用在 CALayer 上的,iOS 和 Mac OS 均可以使用,Core Animation 的動畫過程都是在後臺操做的,不會阻塞主線程。數組

下面是 Core Animation 所涉及的幾個類的繼承關係ide

img

  • CAMediaTiming 協議中定義了時間、速度、重複次數等,包含屬性:佈局

    • beginTime:設置延時時間
    • duration:持續時間
    • speed:動畫速率
    • timeOffset:動畫時間偏移量
    • repeatCount:動畫的重複次數等
    • repeatDuration:重複時間
    • autoreverses:結束後是否反過來恢復到初始值
    • fillMode:當前對象在非對象時間段的初始值
  • CAAnimation 核心動畫基礎類,不能直接使用動畫

    • timingFunction -> 控制動畫的節奏。系統提供的包括:ui

      • kCAMediaTimingFunctionLinear (勻速)
      • kCAMediaTimingFunctionEaseIn (慢進快出)
      • kCAMediaTimingFunctionEaseOut (快進慢出)
      • kCAMediaTimingFunctionEaseInEaseOut (慢進慢出,中間加速)
      • kCAMediaTimingFunctionDefault (默認),固然也可經過自定義建立CAMediaTimingFunction
    • delegate -> 代理。
    • emovedOnCompletion -> 是否讓圖層保持顯示動畫執行後的狀態,默認爲YES,也就是動畫執行完畢後從塗層上移除,恢復到執行前的狀態,若是設置爲NO,而且設置fillMode爲kCAFillModeForwards,則保持動畫執行後的狀態。
  • CAPropertyAnimation 屬性動畫,針對對象的可動畫屬性進行效果的設置,不可直接使用。url

    • keyPath -> CALayer的某個屬性名,並經過這個屬性的值進行修改,達到相應的動畫效果。
    • additive -> 屬性動畫是否以當前動畫效果爲基礎,默認爲NO。
    • cumulative -> 指定動畫是否爲累加效果,默認爲NO。
    • valueFunction -> 此屬性配合CALayer的transform屬性使用。
  • CABasicAnimation基礎動畫,經過keyPath對應屬性進行控制,須要設置fromValue以及toValue,只能在兩個屬性間變化。spa

    • fromValue -> keyPath相應屬性的初始值。
    • toValue -> keyPath相應屬性的結束值。
    • byValue -> 在不設置toValue時,toValue = fromValue + byValue,也就是在當前的位置上增長多少。
  • CASpringAnimation 帶有初始速度以及阻尼指數等物理參數的屬性動畫。

    • mass -> 小球質量,影響慣性
    • stiffness -> 彈簧的勁度係數
    • damping -> 阻尼係數,地面的摩擦力
    • initialVelocity -> 初始速度,至關於給小球一個初始速度(可正可負,方向不一樣)
    • settlingDuration -> 結算時間,根據上述參數計算出的預計時間,相對於你設置的時間,這個時間比較準確。
  • CAKeyframeAnimation 關鍵幀動畫,一樣經過keyPath對應屬性進行控制,但它能夠經過values或者path進行多個階段的控制

    • values -> 關鍵幀組成的數組,動畫會依次顯示其中的每一幀
    • path -> 關鍵幀路徑,動畫進行的要素,優先級比values高,可是隻對CALayer的anchorPoint和position起做用
    • keyTimes -> 每一幀對應的時間,若是不設置,則各關鍵幀平分設定時間
    • timingFunctions -> 每一幀對應的動畫節奏
    • calculationMode -> 動畫的計算模式,系統提供了對應的幾種模式
    • tensionValues -> 動畫張力控制
    • continuityValues -> 動畫連續性控制
    • biasValues -> 動畫誤差率控制
    • rotationMode -> 動畫沿路徑旋轉方式,系統提供了兩種模式。
  • CATransition 轉場動畫,系統提供了不少酷炫效果

    • type -> 轉場動畫類型
    • subtype -> 轉場動畫方向
    • startProgress -> 動畫起點進度(總體的百分比)
    • endProgress -> 動畫終點進度(總體的百分比)
    • filter -> 自定義轉場。
  • CAAnimationGroup 動畫組,方便對於多動畫的統一控制管理。

    • animations -> 全部動畫效果元素的數組。

CABasicAnimation

在通常的應用開發中,基礎動畫能夠知足大部分的開發需求,主要完成對於對象指定動畫屬性兩個Value之間的動畫過渡。

下面展現使用 CABasicAnimation 實現 位移、縮放、透明度、旋轉、圓角 的核心代碼

switch (button.tag) {
        case 0:
            //位移動畫
            basicAni = [CABasicAnimation animationWithKeyPath:@"position"];
            //到達位置
//            basicAni.byValue = [NSValue valueWithCGPoint:CGPointMake(100, 100)];
            basicAni.toValue = [NSValue valueWithCGPoint:CGPointMake(_mainLayer.position.x+100, _mainLayer.position.y+100)];
            break;
        case 1:
            //縮放動畫
            basicAni = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
            //到達縮放
            basicAni.toValue = @(0.1f);
            break;
        case 2:
            //透明度動畫
            basicAni = [CABasicAnimation animationWithKeyPath:@"opacity"];
            //透明度
            basicAni.toValue=@(0.1f);
            break;
        case 3:
            //旋轉動畫
            basicAni = [CABasicAnimation animationWithKeyPath:@"transform"];
            //3D
            basicAni.toValue=[NSValue valueWithCATransform3D:CATransform3DMakeRotation(M_PI_2+M_PI_4, 1, 1, 0)];
            break;
        case 4:
            //圓角動畫
            basicAni = [CABasicAnimation animationWithKeyPath:@"cornerRadius"];
            //圓角
            basicAni.toValue=@(50);
            break;

CASpringAnimation

CASpringAnimation 是 iOS9引入的動畫類,相似於 UIView 的 spring 動畫,可是增長的質量,勁度係數等屬相的擴展,繼承自 CABaseAnimation,用法也比較簡單:

#pragma mark -----------------------CASpringAniamtion 
- (void)initSpringAnimation {
    CASpringAnimation *springAni = [CASpringAnimation animationWithKeyPath:@"position"];
    springAni.damping = 2;
    springAni.stiffness = 50;
    springAni.mass = 1;
    springAni.initialVelocity = 10;
    springAni.toValue = [NSValue valueWithCGPoint:CGPointMake(200, 400)];
    springAni.duration = springAni.settlingDuration;
    [_mainLayer addAnimation:springAni forKey:@"springAnimation"];
}

CAKeyframeAnimation

CAKeyframeAnimation和CABasicAnimation同樣是CApropertyAnimation的子類,可是CABasicAnimation只能從一個數值(fromValue)變到另外一個數值(toValue)或者添加一個增量數值(byValue),而CAKeyframeAnimation使用values數組能夠設置多個關鍵幀,同時能夠利用path能夠進行位置或者錨點的動畫操做

- (void)initKeyframeAnimation {
    CAKeyframeAnimation *animation = nil;
    if (self.animationIndex == 2) {//晃動
        animation = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation"];
        animation.duration = 0.3;
        animation.values = @[@(-(4) / 180.0*M_PI),@((4) / 180.0*M_PI),@(-(4) / 180.0*M_PI)];
        animation.repeatCount=MAXFLOAT;
    }else {//曲線位移
        animation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
        UIBezierPath *path = [UIBezierPath bezierPath];
        [path moveToPoint:_mainLayer.position];
        [path addCurveToPoint:CGPointMake(300, 500) controlPoint1:CGPointMake(100, 400) controlPoint2:CGPointMake(300, 450)];
        animation.path = path.CGPath;
        animation.duration = 1;
        animation.removedOnCompletion = NO;
        animation.fillMode = kCAFillModeForwards;
    }
    [_mainLayer addAnimation:animation forKey:@"keyFrameAnimation"];
}

CATransition

轉場動畫是一種顯示樣式向另外一種顯示樣式過渡的效果,系統給出的效果也不少,不過謹慎使用私有API,防止被拒的悲劇.
具體有如下效果:

  • cube 方塊
  • suckEffect 三角
  • rippleEffect 水波抖動
  • pageCurl 上翻頁
  • pageUnCurl 下翻頁
  • oglFlip 上下翻轉
  • cameraIrisHollowOpen 鏡頭快門開
  • cameraIrisHollowClose 鏡頭快門開
- (void)initCATransitionAnimation {
    CATransition *transition = [CATransition animation];
    transition.type = @"rippleEffect";
    transition.subtype = kCATransitionFromLeft;
    transition.duration = 1;
    _mainLayer.contents = (__bridge id _Nullable)([UIImage imageNamed:@"example"].CGImage);
    [_mainLayer addAnimation:transition forKey:@"transtion"];
}

CAAnimationGroup

在咱們實際開發中,咱們可能須要更加複雜的複合運動,那麼須要給圖層加多個動畫,動畫組也就應運而生,建立動畫組也很簡單,首先建立單個動畫,而後將建立的多個動畫添加到動畫組,最後將動畫組添加圖層上就能夠啦。

- (void)initAnimationGroup {
    //晃動動畫
    CAKeyframeAnimation *keyFrameAni = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation"];
    keyFrameAni.values = @[@(-(4) / 180.0*M_PI),@((4) / 180.0*M_PI),@(-(4) / 180.0*M_PI)];
    //每個動畫能夠單獨設置時間和重複次數,在動畫組的時間基礎上,控制單動畫的效果
    keyFrameAni.duration = 0.3;
    keyFrameAni.repeatCount= MAXFLOAT;
    keyFrameAni.delegate = self;
//    keyFrameAni.removedOnCompletion = NO;
//    keyFrameAni.fillMode = kCAFillModeForwards;
    //位移動畫
    CABasicAnimation *basicAni = [CABasicAnimation animationWithKeyPath:@"position"];
    //到達位置
    basicAni.byValue = [NSValue valueWithCGPoint:CGPointMake(100, 100)];
    //
    basicAni.duration = 1;
    basicAni.repeatCount = 1;
    //
    basicAni.removedOnCompletion = NO;
    basicAni.fillMode = kCAFillModeForwards;
    //設置代理
    basicAni.delegate = self;
    //動畫時間
    basicAni.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    CAAnimationGroup *aniGroup = [CAAnimationGroup animation];
    aniGroup.animations = @[keyFrameAni,basicAni];
    aniGroup.autoreverses = YES;
    //動畫的表現時間和重複次數由動畫組設置的決定
    aniGroup.duration = 2;
    aniGroup.repeatCount= 3;
    //使動畫結束後停留在結束位置
//    aniGroup.autoreverses = NO;
//    aniGroup.removedOnCompletion = NO;
//    aniGroup.fillMode = kCAFillModeForwards;
    //
    [_mainLayer addAnimation:aniGroup forKey:@"groupAnimation"];
    
}

總結

Core Animation 給咱們展現的只是假象;layer 的 frame、bounds、position 不會在動畫完畢後發生改變;
UIView 封裝的動畫會真實修改 view 的一些屬性。

本文總結的內容我的感受仍是比較淺的,但仍是能知足平常開發要求的,固然一些要求比較高的,還須要你們對每一個動畫類進行深刻的研究。

最後附上本文的 Demo 地址 : animation

相關文章
相關標籤/搜索