layer動(dòng)畫屬性總結(jié)

當(dāng)你給一個(gè) CALayer 添加動(dòng)畫的時(shí)候,動(dòng)畫其實(shí)并沒有改變這個(gè) layer 的實(shí)際屬性。取而代之的,系統(tǒng)會(huì)創(chuàng)建一個(gè)原始 layer 的拷貝。在文檔中,蘋果稱這個(gè)原始 layer 為 Model Layer ,而這個(gè)復(fù)制的 layer 則被稱為 Presentation Layer 。 Presentation Layer 的屬性會(huì)隨著動(dòng)畫的進(jìn)度實(shí)時(shí)改變,而 Model Layer 中對(duì)應(yīng)的屬性則并不會(huì)改變。這里就可以引出 removedOnCompletionfillMode 了。

removedOnCompletion 的官方解釋是:

/* When true, the animation is removed from the render tree once its
 * active duration has passed. Defaults to YES. */
/ *當(dāng)為真時(shí),動(dòng)畫從渲染樹中刪除一次
*活動(dòng)時(shí)間已經(jīng)過(guò)去。默認(rèn)值為YES。* /

也就是默認(rèn)情況下系統(tǒng)會(huì)在 duration 時(shí)間后自動(dòng)移除這個(gè) CAKeyframeAnimation。當(dāng) remove 了某個(gè)動(dòng)畫,那么系統(tǒng)就會(huì)自動(dòng)銷毀這個(gè) layer 的 Presentation Layer ,只留下 Model Layer 。 而前面提到 Model Layer 的屬性其實(shí)并沒有變化,所以也就有了你前面看到的結(jié)果,視圖在一瞬間回到了動(dòng)畫的初始狀態(tài)。要解決這種情況,你需要先把removedOnCompletion 設(shè)置為 no ,然后設(shè)置fillMode 為kCAFillModeForwards 。關(guān)于 fillMode ,它有四個(gè)值:
kCAFillModeRemoved 這個(gè)是默認(rèn)值,也就是說(shuō)當(dāng)動(dòng)畫開始前和動(dòng)畫結(jié)束后,動(dòng)畫對(duì)layer都沒有影響,動(dòng)畫結(jié)束后,layer會(huì)恢復(fù)到之前的狀態(tài)。
kCAFillModeForwards 當(dāng)動(dòng)畫結(jié)束后,layer會(huì)一直保持著動(dòng)畫最后的狀態(tài)。
kCAFillModeBackwards 這個(gè)和 kCAFillModeForwards 是相對(duì)的,就是在動(dòng)畫開始前,你只要將動(dòng)畫加入了一個(gè)layer,layer便立即進(jìn)入動(dòng)畫的初始狀態(tài)并等待動(dòng)畫開始。你可以這樣設(shè)定測(cè)試代碼,將一個(gè)動(dòng)畫加入一個(gè)layer的時(shí)候延遲5秒執(zhí)行。然后就會(huì)發(fā)現(xiàn)在動(dòng)畫沒有開始的時(shí)候,只要?jiǎng)赢嫳患尤肓?layer , layer 便處于動(dòng)畫初始狀態(tài), 動(dòng)畫結(jié)束后,layer 也會(huì)恢復(fù)到之前的狀態(tài)。
kCAFillModeBoth 理解了上面兩個(gè),這個(gè)就很好理解了,這個(gè)其實(shí)就是上面兩個(gè)的合成。動(dòng)畫加入后立即開始,layer便處于動(dòng)畫初始狀態(tài),動(dòng)畫結(jié)束后layer保持動(dòng)畫最后的狀態(tài)。
calculationMode 設(shè)置是否勻速線性運(yùn)動(dòng)
默認(rèn)是kCAAnimationLinear線性運(yùn)動(dòng)走直角
const kCAAnimationLinear//線性,默認(rèn)
2 const kCAAnimationDiscrete//離散,無(wú)中間過(guò)程,但keyTimes設(shè)置的時(shí)間依舊生效,物體跳躍地出現(xiàn)在各個(gè)關(guān)鍵幀上
3 const kCAAnimationPaced//平均,keyTimes跟timeFunctions失效
4 const kCAAnimationCubic//平均,同上
5 const kCAAnimationCubicPaced//平均,同上

屬性理解

duration 動(dòng)畫的時(shí)長(zhǎng)
repeatCount 重復(fù)的次數(shù)。不停重復(fù)設(shè)置為 HUGE_VALF
repeatDuration 設(shè)置動(dòng)畫的時(shí)間。在該時(shí)間內(nèi)動(dòng)畫一直執(zhí)行,不計(jì)次數(shù)。
beginTime 指定動(dòng)畫開始的時(shí)間。從開始延遲幾秒的話,設(shè)置為【CACurrentMediaTime() + 秒數(shù)】 的方式
timingFunction 設(shè)置動(dòng)畫的速度變化
autoreverses 動(dòng)畫結(jié)束時(shí)是否執(zhí)行逆動(dòng)畫
fromValue 所改變屬性的起始值
toValue 所改變屬性的結(jié)束時(shí)的值
byValue 所改變屬性相同起始值的改變量

UIView *aView0 = [[UIView alloc] initWithFrame:CGRectMake(150, 100, 50, 50)];
    [self.view addSubview:aView0];
    aView0.backgroundColor = [UIColor purpleColor];
    
    //旋轉(zhuǎn)動(dòng)畫
    //transform.rotation 默認(rèn)圍繞z軸
    CAKeyframeAnimation *animation11 = [CAKeyframeAnimation animation];
    animation11.keyPath = @"transform.rotation.z";
    animation11.values = @[@0, @(M_PI*2)];
    animation11.duration = 5;
    animation11.repeatCount = MAXFLOAT;
    animation11.calculationMode = kCAAnimationCubic;
    animation11.removedOnCompletion = NO;
    animation11.fillMode = kCAFillModeForwards;
    [aView0.layer addAnimation:animation11 forKey:nil];

    //縮放動(dòng)畫
    CAKeyframeAnimation *animation11 = [CAKeyframeAnimation animation];
    animation11.keyPath = @"transform.scale";
    animation11.values = @[@1.0,@1.2,@0.9,@1.15,@0.95,@1.05,@1.0];
    animation11.duration = 5;
    animation11.repeatCount = MAXFLOAT;
    animation11.calculationMode = kCAAnimationCubic;
    [aView0.layer addAnimation:animation11 forKey:nil];

    //位移動(dòng)畫 設(shè)置偏移距離
    CAKeyframeAnimation *animation11 = [CAKeyframeAnimation animation];
    animation11.keyPath = @"transform.translation.x";
    animation11.values = @[@1, @-100.0,@110];
    animation11.duration = 5;
    animation11.repeatCount = 1;
    animation11.calculationMode = kCAAnimationCubic;
    animation11.removedOnCompletion = NO;
    animation11.fillMode = kCAFillModeForwards;
    [aView0.layer addAnimation:animation11 forKey:nil];

// 位移動(dòng)畫   設(shè)置 運(yùn)動(dòng)坐標(biāo)點(diǎn)
    CAKeyframeAnimation *animation11 = [CAKeyframeAnimation animation];
    animation11.keyPath = @"transform.translation";
    animation11.values = @[@(CGPointMake(0, 0)),@(CGPointMake(100, 200)), @(CGPointMake(50, 200))];
    animation11.duration = 1;
    animation11.repeatCount = 1;
    animation11.calculationMode = kCAAnimationLinear;//這里是線性 如果轉(zhuǎn)彎的話不會(huì)飄;

    /*
     const kCAAnimationLinear//線性,默認(rèn)
     2 const kCAAnimationDiscrete//離散,無(wú)中間過(guò)程,但keyTimes設(shè)置的時(shí)間依舊生效,物體跳躍地出現(xiàn)在各個(gè)關(guān)鍵幀上
     3 const kCAAnimationPaced//平均,keyTimes跟timeFunctions失效
     4 const kCAAnimationCubic//平均,同上
     5 const kCAAnimationCubicPaced//平均,同上
     */
    animation11.autoreverses = NO;
    animation11.removedOnCompletion = NO;
    animation11.fillMode = kCAFillModeForwards;
    [aView0.layer addAnimation:animation11 forKey:nil];

    //設(shè)置 透明度
    CAKeyframeAnimation *animation11 = [CAKeyframeAnimation animation];
    animation11.keyPath = @"opacity";
    animation11.values = @[@1.0, @0.7, @0.4, @0.8, @0.1, @0.5, @0.2];
    animation11.duration = 2;
    animation11.repeatCount = 1;
    animation11.calculationMode = kCAAnimationCubic;
    animation11.autoreverses = NO;
    animation11.removedOnCompletion = NO;
    animation11.fillMode = kCAFillModeForwards;
    [aView0.layer addAnimation:animation11 forKey:nil];

    //圓角
    CAKeyframeAnimation *animation11 = [CAKeyframeAnimation animation];
    animation11.keyPath = @"cornerRadius";
    animation11.values = @[@0, @20, @25, @25, @0, @25];
    animation11.duration = 2;
    animation11.repeatCount = 1;
    animation11.calculationMode = kCAAnimationCubic;
    animation11.autoreverses = NO;
    animation11.removedOnCompletion = NO;
    animation11.fillMode = kCAFillModeForwards;
    [aView0.layer addAnimation:animation11 forKey:nil];


    //邊框?qū)挾?    CAKeyframeAnimation *animation11 = [CAKeyframeAnimation animation];
    animation11.keyPath = @"borderWidth";
    animation11.values = @[@0, @20, @10, @0, @10];
    animation11.duration = 2;
    animation11.repeatCount = 1;
    animation11.calculationMode = kCAAnimationCubic;
    animation11.autoreverses = NO;
    animation11.removedOnCompletion = NO;
    animation11.fillMode = kCAFillModeForwards;
    aView0.layer.borderColor = [UIColor redColor].CGColor;
    [aView0.layer addAnimation:animation11 forKey:nil];
    
    
    //bounds大小
    CAKeyframeAnimation *animation11 = [CAKeyframeAnimation animation];
    animation11.keyPath = @"bounds";
    animation11.values = @[@(CGRectMake(0, 0, 50, 50)), @(CGRectMake(0, 0, 100, 120)), @(CGRectMake(0, 0, 70, 50))];
    animation11.duration = 2;
    animation11.repeatCount = 1;
    animation11.calculationMode = kCAAnimationCubic;
    animation11.autoreverses = NO;
    animation11.removedOnCompletion = NO;
    animation11.fillMode = kCAFillModeForwards;
    [aView0.layer addAnimation:animation11 forKey:nil];
    
    //位移動(dòng)畫  設(shè)置點(diǎn)
    CAKeyframeAnimation *animation11 = [CAKeyframeAnimation animation];
    animation11.keyPath = @"position";
    animation11.values = @[[NSValue valueWithCGPoint:CGPointMake(150, 100)],[NSValue valueWithCGPoint:CGPointMake(300, 300)],[NSValue valueWithCGPoint:CGPointMake(300, 200)]];
    animation11.duration = 2;
    animation11.repeatCount = 1;
    animation11.calculationMode = kCAAnimationLinear;//這里是線性 如果轉(zhuǎn)彎的話不會(huì)飄
    animation11.autoreverses = NO;
    animation11.removedOnCompletion = NO;
    animation11.fillMode = kCAFillModeForwards;
    [aView0.layer addAnimation:animation11 forKey:nil];
//組合動(dòng)畫
//位置在y周平移
CABasicAnimation *positionAnima = [CABasicAnimation animationWithKeyPath:@"position.y"];
    positionAnima.fromValue = @(bgImageView.center.y);
    positionAnima.toValue = @(bgImageView.center.y-30);
    positionAnima.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
    //相對(duì)y周旋轉(zhuǎn)
    CABasicAnimation *transformAnima = [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"];
    transformAnima.fromValue = @(0);
    transformAnima.toValue = @(M_PI);
    transformAnima.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    //組合動(dòng)畫類
    CAAnimationGroup *animaGroup = [CAAnimationGroup animation];
    animaGroup.duration = 2.0f;
    animaGroup.fillMode = kCAFillModeForwards;
    animaGroup.removedOnCompletion = NO;
    animaGroup.autoreverses = YES;
    animaGroup.repeatCount = CGFLOAT_MAX;
//添加組合動(dòng)畫
    animaGroup.animations = @[positionAnima,transformAnima];
    //添加到實(shí)現(xiàn)動(dòng)畫對(duì)象的layer
    [bgImageView.layer addAnimation:animaGroup forKey:@"Animation"];
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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