OC動畫的幾種實(shí)現(xiàn)方式

一. 序列幀動畫

序列幀動畫和我們小時(shí)候看的小人書是一樣的,由連續(xù)的很多張的畫面組成,每一張都與前一張稍有不同,快速翻動的時(shí)候就是一個(gè)動畫了。序列幀動畫就是通過UIImageView,快速一幀一幀的播放圖片實(shí)現(xiàn)的動畫效果。

    NSMutableArray *imageArray = [NSMutableArray array];
    for (int i=1; i<50; i++) {
        NSString *source = [[NSBundle mainBundle] resourcePath];
        NSString *imgPath = [source stringByAppendingPathComponent:[NSString stringWithFormat:@“gifImage%d”, i]];
        [imageArray addObject:[UIImage imageWithContentsOfFile:imgPath]];
    }
    [self.alignmentView setAnimationImages:imageArray];
    [self.alignmentView setAnimationRepeatCount:1];
    [self.alignmentView setAnimationDuration:4];
    [self.alignmentView startAnimating];
bicycle.gif

代碼中使用imageWithContentsOfFile而沒有使用imageNamed的原因:
imageWithContentsOfFile不會將圖片緩存,圖片所占內(nèi)存在使用后就會清除
imageNamed使用的圖片會緩存下來,運(yùn)行內(nèi)存占用比較高

二. UIView動畫

UIView動畫實(shí)際上就是UIView對核心動畫的封裝,通過更簡單的設(shè)置就可以實(shí)現(xiàn)很多常用的動畫效果。UIView動畫是作用在CALayer上的,可以用來做動畫的屬性有frame,bounds,alpha,transform,backgroundColor,基本上能滿足大多數(shù)的動畫需要。

    [UIView animateWithDuration:4 animations:^{
        //center -- 視圖位置
        CGPoint center = self.animationView.center;
        center.y += 100;
        self.animationView.center = center;
        //alpha -- 透明度
        self.animationView.alpha = 0.2;
        //transform -- 旋轉(zhuǎn)加縮放
        self.animationView.transform = CGAffineTransformRotate(self.animationView.transform, M_PI_4);
        self.animationView.transform = CGAffineTransformScale(self.animationView.transform, 0.5, 0.5);
    }];
uiviewAnimation.gif

同樣的還有:

    //可以檢測動畫結(jié)束
    [UIView animateWithDuration:4 animations:^{
        //動畫設(shè)置
    } completion:^(BOOL finished) {
        //動畫結(jié)束后執(zhí)行的操作
    }];
    //可以設(shè)置延遲時(shí)間,以及檢測動畫執(zhí)行結(jié)束
    [UIView animateWithDuration:4 delay:1 options:UIViewAnimationOptionAutoreverse animations:^{
        //動畫設(shè)置
    } completion:^(BOOL finished) {
        //動畫結(jié)束后執(zhí)行的操作
    }];
    //彈性動畫,參數(shù)說明:01 持續(xù)時(shí)間, 02 延遲時(shí)間, 03 彈簧強(qiáng)度 0.0 - 1.0, 04 開始變化速度, 05 動畫效果參數(shù)
    [UIView animateWithDuration:10 delay:0 usingSpringWithDamping:0.05 initialSpringVelocity:1 options:UIViewAnimationOptionCurveEaseInOut animations:^{
        //動畫設(shè)置
    } completion:^(BOOL finished) {
        //動畫結(jié)束執(zhí)行的操作
    }];

三. 核心動畫

核心動畫就是設(shè)置動畫的運(yùn)動路徑或關(guān)鍵點(diǎn),然后將這些屬性值添加到CALayer,再設(shè)置動畫的執(zhí)行時(shí)間,方向,代理等。
核心動畫的結(jié)構(gòu):

核心動畫類結(jié)構(gòu).png

核心動畫層次結(jié)構(gòu):
層次結(jié)構(gòu).png

CAAnimation是所有動畫對象的父類,遵守CAMediaTiming協(xié)議,實(shí)現(xiàn)的功能是控制動畫時(shí)間,重復(fù)次數(shù),填充模式等,是一個(gè)抽象類,不能直接使用。
核心動畫類中可以直接使用的類有:
CABasicAnimation 基本動畫
CAKeyframeAnimation 關(guān)鍵幀動畫
CASpringAnimation 彈性動畫
CATransition 轉(zhuǎn)場動畫
CAAnimationGroup 動畫組

1. CABasicAnimation

CABasicAnimation可以看作是只有兩個(gè)關(guān)鍵點(diǎn)的CAKeyFrameAnimation,動畫的效果就是從起點(diǎn)進(jìn)行到終點(diǎn)。
對圖形位置做動畫:

    //因?yàn)闆]有設(shè)置動畫的結(jié)束狀態(tài),默認(rèn)情況下動畫執(zhí)行結(jié)束圖形會回到初始位置
    CABasicAnimation *basicAnimation = [CABasicAnimation animationWithKeyPath:@"position.y"];
    basicAnimation.fromValue = @(self.animationView.center.y);
    basicAnimation.toValue = @(self.animationView.center.y + 30);
    basicAnimation.repeatCount = 3;
    basicAnimation.duration = 1;
    [self.animationView.layer addAnimation:basicAnimation forKey:nil];
positionY.gif

圖形的旋轉(zhuǎn)動畫:

    CABasicAnimation *basicAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"];
    basicAnimation.fromValue = @(0);
    basicAnimation.toValue = @(M_PI);
    basicAnimation.repeatCount = 1;
    basicAnimation.duration = 1;
    //若要將removedOnCompletion設(shè)置為NO,fillMode必須設(shè)置為kCAFillModeForwards
    basicAnimation.fillMode = kCAFillModeForwards;
    //若要將removedOnCompletion設(shè)置為NO表示動畫結(jié)束后圖形不會回到初始狀態(tài)
    basicAnimation.removedOnCompletion = NO;
    [self.animationView.layer addAnimation:basicAnimation forKey:nil];
transformRotationY.gif

transformRotationX.gif
transformRotationZ.gif

2. CAKeyframeAnimation

values:設(shè)置一個(gè)關(guān)鍵幀的對象數(shù)組,每個(gè)元素都是一個(gè)關(guān)鍵幀,動畫在對應(yīng)的時(shí)間段內(nèi)執(zhí)行數(shù)組中的每一個(gè)關(guān)鍵幀動畫
path:動畫路徑對象,為動畫指定一個(gè)路徑,動畫圖形沿著路徑移動
keyTimes:設(shè)置關(guān)鍵幀之間的動畫所占用的動畫時(shí)長比例(0-1),若不設(shè)置,則每一幀的時(shí)間平分
可以做動畫的關(guān)鍵幀有:anchorPoint backgroundColor borderColor borderWidth bounds contents contentsRect cornerRadius doubleSided frame hidden mask maskToBounds opacity position shadowColor shadowOffset shadowOpacity shadowPath shadowRadius sublayers sublayerTransform transform

    CAKeyframeAnimation *keyAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    //確定路徑上的幾個(gè)錨點(diǎn)
    NSValue *value1 = [NSValue valueWithCGPoint:self.animationView.center];
    NSValue *value2 = [NSValue valueWithCGPoint:CGPointMake(self.view.bounds.size.width/2 + 100, 300)];
    NSValue *value3 = [NSValue valueWithCGPoint:CGPointMake(self.view.bounds.size.width/2, 400)];
    NSValue *value4 = [NSValue valueWithCGPoint:CGPointMake(self.view.bounds.size.width/2 - 100, 300)];
    //將幾個(gè)錨點(diǎn)連接起來繪制動畫的路徑
    keyAnimation.values = @[value1,value2,value3,value4,value1];
    keyAnimation.duration = 3;
    keyAnimation.repeatCount = 2;
    [self.animationView.layer addAnimation:keyAnimation forKey:nil];
positionValues.gif
    CAKeyframeAnimation *keyAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    UIBezierPath *circlePath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(self.animationView.center.x, self.animationView.center.y+100) radius:100 startAngle:-M_PI_2 endAngle:3.0*M_PI_2 clockwise:YES];
    keyAnimation.path = circlePath.CGPath;
    keyAnimation.repeatCount = 2;
    keyAnimation.duration = 2;
    [self.animationView.layer addAnimation:keyAnimation forKey:nil];
positionPath.gif

3. CASpringAnimation

UIView的彈性動畫就是對CASpringAnimation的簡單封裝,可以完成簡單的彈性動畫,CASpringAnimation功能更強(qiáng)大,能夠?qū)崿F(xiàn)更復(fù)雜的彈性動畫效果。重要屬性:
mass:質(zhì)量,質(zhì)量越大,彈簧的慣性越大
stiffness:彈性系數(shù),彈性系數(shù)越大,運(yùn)動越快
damping:阻尼系數(shù),阻尼越大,彈簧的運(yùn)動停止越快
initialVelocity:初始速度
settlingDuration:執(zhí)行時(shí)間

    CASpringAnimation *springAnimation = [CASpringAnimation animationWithKeyPath:@"bounds"];
    springAnimation.mass = 1;
    springAnimation.stiffness = 1000;
    springAnimation.damping = 20;
    springAnimation.initialVelocity = 50;
    springAnimation.duration = springAnimation.settlingDuration;
    springAnimation.fromValue = @(self.animationView.bounds);
    CGRect newBounds = CGRectMake(self.animationView.bounds.origin.x, self.animationView.bounds.origin.y, self.animationView.bounds.size.width+80, self.animationView.bounds.size.height);
    springAnimation.toValue = @(newBounds);
    springAnimation.fillMode = kCAFillModeForwards;
    springAnimation.removedOnCompletion = NO;
    springAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    [self.animationView.layer addAnimation:springAnimation forKey:nil];
springScale.gif
springPosition.gif

4. CATransition

CATransition提供了四種動畫效果,私有的幾種動畫效果已經(jīng)禁止使用。通過type屬性設(shè)置動畫的類型,通過subtype設(shè)置動畫的方向。

    CATransition *transition = [CATransition animation];
    //公開kCATransitionMoveIn,Push,Reveal,Fade
    //私有cube,suckEffect,oglFlip,rippleEffect,pageCurl,pageUnCurl
    transition.type = kCATransitionPush;
    transition.subtype = kCATransitionFromLeft;
    transition.duration = 0.5;
    UIColor *red = [UIColor redColor];
    UIColor *orange = [UIColor orangeColor];
    UIColor *yellow = [UIColor yellowColor];
    UIColor *green = [UIColor greenColor];
    UIColor *blue = [UIColor blueColor];
    UIColor *purple = [UIColor purpleColor];
    NSArray *colorArr = @[red,orange,yellow,green,blue,purple];
    self.animationView.backgroundColor = colorArr[count];
    [self.animationView.layer addAnimation:transition forKey:nil];
    count = count==5?0:count+1;
transitionPush.gif
transitionMoveIn.gif
transitionReveal.gif
transitionFade.gif

5. CAAnimationGroup

組動畫可以將多個(gè)動畫效果一起添加到CALayer上,多個(gè)動畫同時(shí)執(zhí)行,實(shí)現(xiàn)更復(fù)雜更生動的效果。

    //圓形路徑的動畫
    CAKeyframeAnimation *keyAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    UIBezierPath *circlePath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(self.animationView.center.x, self.animationView.center.y+100) radius:100 startAngle:-M_PI_2 endAngle:3.0*M_PI_2 clockwise:YES];
    keyAnimation.path = circlePath.CGPath;
    //大小動畫
    CAKeyframeAnimation *keyAnimation2 = [CAKeyframeAnimation animationWithKeyPath:@"transform.scale"];
    keyAnimation2.values = @[@(1.0),@(0.9),@(0.8),@(0.7),@(0.6),@(0.5),@(0.6),@(0.7),@(0.8),@(0.9),@(1.0)];
    //創(chuàng)建組動畫
    CAAnimationGroup *group = [CAAnimationGroup animation];
    group.animations = @[keyAnimation,keyAnimation2];
    group.duration = 5;
    group.repeatCount = 3;
    [self.animationView.layer addAnimation:group forKey:nil];
groupAnimation.gif

以上就是對我們對幾種經(jīng)常使用的動畫形式的簡單介紹,使用這些方式能夠幫助我們實(shí)現(xiàn)大多數(shù)簡單的動畫效果。

參考:iOS動畫篇:核心動畫

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容