iOS動畫之平移篇

就像之前說的,所有的動畫都是在CALayer上面的。所以在做動畫之前我們就要先建立一個CALayer,然后把動畫作用在自己創(chuàng)建的這個CALayer上。如果不知道CALyer是啥,可以看看前面的分享哈。傳輸門:iOS時鐘動畫效果實(shí)現(xiàn)

最終實(shí)現(xiàn)的效果:

基礎(chǔ)動畫之平移效果

1. 基礎(chǔ)版的平移

這里重點(diǎn)是為了演示fromValue/toValue 、 設(shè)置layer的Position位置、實(shí)現(xiàn)代理方法里面設(shè)置position的區(qū)別。

最終實(shí)現(xiàn)的效果:

步驟如下:
1, 創(chuàng)建CALayer。
2, 設(shè)置CALayer的位置、大小、背景顏色。
3, 將自定義的CALayer添加到主視圖的view上面。
4, 實(shí)例化一個CABasicAnimation對象。
5, 設(shè)置動畫屬性為平移。
6, 設(shè)置動畫的起始位置,從哪里到哪里。
7,設(shè)置動畫的持續(xù)時間、填充模式、重復(fù)次數(shù)、設(shè)置代理。
8, 將動畫添加到需要作用的CALayer上面。
9, 實(shí)現(xiàn)<CAAnimationDelegate>的代理方法:動畫開始時調(diào)用的方法、動畫結(jié)束時調(diào)用的方法。

//遵守動畫的代理協(xié)議
@interface STBasicPositionViewController ()<CAAnimationDelegate>
@property(weak,nonatomic)CALayer * redLayer;

@end

@implementation STBasicPositionViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    //創(chuàng)建CALayer
    CALayer *redLayer = [CALayer layer];

    //設(shè)置位置和大小
    redLayer.position = CGPointMake(200, 200);
    redLayer.bounds = CGRectMake(0, 0, 100, 100);

    //設(shè)置背景顏色
    redLayer.backgroundColor = [UIColor redColor].CGColor;

    //把layer添加到UIView的layer上
    [self.view.layer addSublayer:redLayer];

    self.redLayer = redLayer;

    /*------------開始設(shè)置動畫------------------------*/

    //創(chuàng)建動畫對象
    CABasicAnimation *basicAni = [CABasicAnimation animation];

    //設(shè)置動畫屬性
    basicAni.keyPath = @"position";

    //設(shè)置動畫的起始位置。也就是動畫從哪里到哪里
    basicAni.fromValue = [NSValue valueWithCGPoint:CGPointMake(0, 0)];

    //動畫結(jié)束后,layer所在的位置
    basicAni.toValue = [NSValue valueWithCGPoint:CGPointMake(300, 300)];

    //動畫持續(xù)時間
    basicAni.duration = 2;

    //動畫填充模式
    basicAni.fillMode = kCAFillModeForwards;

    //動畫完成不刪除
    basicAni.removedOnCompletion = NO;

    //xcode8.0之后需要遵守代理協(xié)議
    basicAni.delegate = self;

    //把動畫添加到要作用的Layer上面
    [self.redLayer addAnimation:basicAni forKey:nil];

}

#pragma 實(shí)現(xiàn)代理協(xié)議的方法

//動畫開始的時候調(diào)用
- (void)animationDidStart:(CAAnimation *)anim{

    self.redLayer.position = CGPointMake(300, 100);

}

//動畫結(jié)束的時候調(diào)用
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{

    self.redLayer.position = CGPointMake(300, 400);
}

@end

2. 創(chuàng)建不同速度控制的動畫

上面代碼里面我們看到了有一些莫名其妙出來的字符串,例如在設(shè)置動畫屬性的時候出來的:

    //設(shè)置動畫屬性
    basicAni.keyPath = @"position";

    //動畫填充模式
    basicAni.fillMode = kCAFillModeForwards;

這些屬性,在前一篇很枯燥的分享里面有提到。有需要的童鞋可以點(diǎn)進(jìn)去當(dāng)作字典翻一下。也沒有啥記憶的必要性,需要的時候查一下,需要的時候查一下就好了。傳輸門:iOS動畫:Core Animation。介紹了Core Animation的常用屬性和方法。

速度控制一共有四種模式:

kCAMediaTimingFunctionLinear(線性):勻速,給你一個相對靜態(tài)的感覺
kCAMediaTimingFunctionEaseIn(漸進(jìn)):動畫緩慢進(jìn)入,然后加速離開
kCAMediaTimingFunctionEaseOut(漸出):動畫全速進(jìn)入,然后減速的到達(dá)目的地
kCAMediaTimingFunctionEaseInEaseOut(漸進(jìn)漸出):動畫緩慢的進(jìn)入,中間加速,然后減速的到達(dá)目的地。這個是默認(rèn)的動畫行為。

2.1 抽取創(chuàng)建Layer及動畫的公共方法

為了能夠偷點(diǎn)懶,所以抽取了公共的方法。可以很方便的創(chuàng)建Layer以及動畫。哈哈,本宅胖要是不懶就不會這么胖了。

#pragma 抽取創(chuàng)建動畫及Layer的公共方法

//創(chuàng)建CALayer
- (CALayer *)createLayerWithPosition:(CGPoint)position backgroundColor:(UIColor *)backgroundColor{
    //創(chuàng)建CALayer
    CALayer *layer = [CALayer layer];

    //設(shè)置位置和大小
    layer.position = position;
    layer.bounds = CGRectMake(0, 0, 100, 100);

    //設(shè)置背景顏色
    layer.backgroundColor = backgroundColor.CGColor;

    //把layer添加到UIView的layer上
    [self.view.layer addSublayer:layer];

    return layer;
}

//創(chuàng)建動畫
- (CABasicAnimation *)createBasicAnimationWithFromValue:(CGPoint)fromValue toValue:(CGPoint)toValue timingFunction:(NSString *)timingFunction{
    //創(chuàng)建動畫對象
    CABasicAnimation *basicAni = [CABasicAnimation animation];

    //設(shè)置動畫屬性
    basicAni.keyPath = @"position";

    //設(shè)置動畫的起始位置。也就是動畫從哪里到哪里
    basicAni.fromValue = [NSValue valueWithCGPoint:fromValue];

    //動畫結(jié)束后,layer所在的位置
    basicAni.toValue = [NSValue valueWithCGPoint:toValue];

    //動畫持續(xù)時間
    basicAni.duration = 2;

    //動畫重復(fù)次數(shù)
    basicAni.repeatCount = CGFLOAT_MAX;

    //xcode8.0之后需要遵守代理協(xié)議
    basicAni.delegate = self;

    basicAni.timingFunction = [CAMediaTimingFunction functionWithName:timingFunction];

    return basicAni;
}

2.2 創(chuàng)建Layer和動畫

這里我們只創(chuàng)建一個為例。

    //    創(chuàng)建紅色線性運(yùn)動的Layer
    self.redLayer = [self createLayerWithPosition:CGPointMake(0, 150) backgroundColor:[UIColor redColor]];
    [self.redLayer addAnimation:[self createBasicAnimationWithFromValue:CGPointMake(0, 150) toValue:CGPointMake(300, 150) timingFunction:kCAMediaTimingFunctionLinear] forKey:@"linear"];

有朋友可能發(fā)現(xiàn)了,為啥添加動畫的時候后面的forKey怎么不是之前的nil了呢?
這里添加一個key值,實(shí)際上是為這個動畫對象起了一個名字,通過key值,可以很方便的取到這個動畫對象

2.3 移除動畫

動畫播放完成之后,我們通過key值將這個動畫移除掉。
這個方法當(dāng)然是在動畫結(jié)束的時候調(diào)用最合適,不然動畫還沒放完就移除了豈不是開天窗啦~
CAAnimationDelegate這個里面的代理方法終于起到作用了。

//動畫結(jié)束的時候調(diào)用
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{
    [self.redLayer removeAnimationForKey:@"linear"];

    [self.blueLayer removeAnimationForKey:@"easeIn"];

    [self.grayLayer removeAnimationForKey:@"easeOut"];

    [self.greenLayer removeAnimationForKey:@"easeInAndEaseOut"];

}

3. Swift版本的部分差異

Swift版本幾乎和OC的一模一樣。略有不同的是,swift在加載layer的時候,我們使用了懶加載的方式。也就是在使用的時候才去創(chuàng)建這個layer。

源代碼也放在了碼云上面。

    //MARK: - 懶加載

    private lazy var redLayer: CALayer = {
        let layer = self.createLayer(position: CGPoint(x: 0, y: 150), backgroundColor: UIColor.red)

        return layer
    }()

8.總結(jié) + Demo

以上是實(shí)現(xiàn)了iOS動畫平移效果了,如果需要動畫平移 Demo,可以加iOS高級技術(shù)交流群:937194184,獲取Demo,以及更多iOS學(xué)習(xí)資料.

收錄:原文地址

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

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