CoreAnimation(二)-CAPropertyAnimation

CAPropertyAnimation也是一個(gè)抽象類,自身并不能對(duì)layer進(jìn)行動(dòng)畫操作,需要其子類CABasicAnimation和CAKeyframeAnimation來(lái)實(shí)現(xiàn)動(dòng)畫操作。
屬性解讀:

屬性 描述
keyPath 指定接收層動(dòng)畫的關(guān)鍵路徑(入門篇提供了部分keyPath,敬請(qǐng)參考)
cumulative 下一次動(dòng)畫執(zhí)行是否接著剛才的動(dòng)畫,默認(rèn)為false
additive 如何處理多個(gè)動(dòng)畫在同一時(shí)間段執(zhí)行的結(jié)果,若為true,同一時(shí)間段的動(dòng)畫合成為一個(gè)動(dòng)畫,默認(rèn)為false。(使用 CAKeyframeAnimation 時(shí)必須將該屬性指定為 true ,否則不會(huì)出現(xiàn)期待的結(jié)果)

一、CABasicAnimation(基礎(chǔ)動(dòng)畫)

該子類中有三個(gè)屬性:fromValue、byValue、toValue,主要用來(lái)操作縮放、平移和旋轉(zhuǎn)等簡(jiǎn)單動(dòng)畫。隨著動(dòng)畫的進(jìn)行,在長(zhǎng)度為duration的持續(xù)時(shí)間內(nèi),keyPath相應(yīng)屬性的值會(huì)在任意一個(gè)或兩個(gè)屬性值的范圍內(nèi)漸變。

fromValue:keyPath相應(yīng)屬性的初始值
byValue:keyPaht相應(yīng)屬性的相對(duì)插值
toValue:keyPath相應(yīng)屬性的結(jié)束值

有如下幾種情況:

  • fromValue和toValue不為nil,keyPath屬性值在fromValue與toValue之間漸變
  • fromValue和byValue不為nil,keyPath屬性值在fromValue與(fromValue+byValue)之間漸變
  • byValue和toValue不為nil,keyPath屬性值在(toValue-byValue)與toValue之間漸變
  • fromValue不為nil,keyPath屬性值在fromValue與圖層對(duì)應(yīng)當(dāng)前值之間漸變
  • toValue不為nil,keyPath屬性值在圖層對(duì)應(yīng)當(dāng)前值與toValue之間漸變
  • byValue不為nil,keyPath屬性值在圖層對(duì)應(yīng)當(dāng)前值與(圖層對(duì)應(yīng)當(dāng)前值+toValue)之間漸變

注意:value的值可以設(shè)置為CATransform3D的對(duì)象,實(shí)現(xiàn)3D動(dòng)畫效果!

旋轉(zhuǎn)動(dòng)畫
  //默認(rèn)是繞著z軸旋轉(zhuǎn),也可指定繞某個(gè)軸旋轉(zhuǎn):transform.rotation.x
  let animation = CABasicAnimation(keyPath: "transform.rotation")
  //只設(shè)置toValue,動(dòng)畫會(huì)在圖層對(duì)應(yīng)當(dāng)前值與toValue之間漸變
  animation.toValue = M_PI * 2
  //設(shè)置動(dòng)畫重復(fù)次數(shù)
  animation.repeatCount = MAXFLOAT
  //設(shè)置動(dòng)畫執(zhí)行時(shí)間
  animation.duration = 1
  //添加動(dòng)畫到layer
  redView.layer.addAnimation(animation, forKey: nil)
縮放動(dòng)畫
  //transform.scale默認(rèn)是x,y,z三個(gè)方向同時(shí)同比例縮放,也可指定某一個(gè)方向縮放
  let animation = CABasicAnimation(keyPath: "transform.scale")
  //只設(shè)置fromValue動(dòng)畫會(huì)在fromValue與圖層對(duì)應(yīng)當(dāng)前值之前漸變
  animation.fromValue = -CGRectGetWidth(view.bounds)
  //設(shè)置動(dòng)畫重復(fù)次數(shù)
  animation.repeatCount = MAXFLOAT
  //設(shè)置動(dòng)畫執(zhí)行時(shí)間
  animation.duration = 1
  //添加動(dòng)畫到layer,添加動(dòng)畫的key可以為nil,也可以為任意值,是用來(lái)在CAAnimation協(xié)議方法中區(qū)分不同動(dòng)畫,相當(dāng)于UIView的tag
  greenView.layer.addAnimation(animation, forKey: nil)
平移動(dòng)畫:
  //keyPath可設(shè)置為x,y,z在對(duì)應(yīng)方向平移或者直接寫成transform.translation,在x和y方向同時(shí)平移
  let animation = CABasicAnimation(keyPath: "transform.translation.x")
  animation.fromValue = -CGRectGetWidth(view.bounds)
  animation.toValue = CGRectGetWidth(view.bounds)
  //設(shè)置動(dòng)畫重復(fù)次數(shù)
  animation.repeatCount = MAXFLOAT
  //設(shè)置動(dòng)畫執(zhí)行時(shí)間
  animation.duration = 1
  //添加動(dòng)畫到layer
  blueView.layer.addAnimation(animation, forKey: nil)

動(dòng)畫效果圖:



二、CAKeyframeAnimation

CALayer的關(guān)鍵幀動(dòng)畫與UIView的關(guān)鍵幀動(dòng)畫類似,UIView的動(dòng)畫可以看做是核心動(dòng)畫的簡(jiǎn)單封裝。關(guān)鍵幀動(dòng)畫的值可以指定為一個(gè)值數(shù)組或者一個(gè)路徑,和CABasicAnimation不同的是,關(guān)鍵幀動(dòng)畫在同一時(shí)間內(nèi)對(duì)同一layer可以做多種不同動(dòng)畫,并且可以控制各動(dòng)畫的執(zhí)行節(jié)奏。CAKeyframeAnimation常用的兩個(gè)屬性是valuesduration,這兩個(gè)屬性就可以簡(jiǎn)單的設(shè)置動(dòng)畫了,其余屬性提供了更加細(xì)致化,更加強(qiáng)大的功能!
屬性解讀:

  • values:關(guān)鍵幀動(dòng)畫值的數(shù)組,當(dāng)path為nil時(shí)設(shè)置有效,否則優(yōu)先選擇屬性path做動(dòng)畫
  • path:動(dòng)畫執(zhí)行的點(diǎn)路徑(通過(guò)Core Graphics提供的API來(lái)繪制路徑),設(shè)置了path,values將被忽略
  • keyTimes:關(guān)鍵幀動(dòng)畫每幀動(dòng)畫開(kāi)始執(zhí)行時(shí)間點(diǎn)的數(shù)組,取值范圍為0~1,數(shù)組中相鄰兩個(gè)值必須遵循后一個(gè)值大于或等于前一個(gè)值,并且最后的值不能為大于1。設(shè)置的時(shí)候與calculationMode有關(guān),具體請(qǐng)查看文檔。未設(shè)置時(shí)默認(rèn)每幀動(dòng)畫執(zhí)行時(shí)間平均(公式:總時(shí)間/(總幀數(shù)-1))。例如,如果你指定了一個(gè)5幀,10秒的動(dòng)畫,那么每幀的時(shí)間就是2.5秒鐘:10 /(5-1)=2.5
  • rotationMode:設(shè)置路徑旋轉(zhuǎn),當(dāng)設(shè)置path有不同角度時(shí),會(huì)自動(dòng)旋轉(zhuǎn)layer角度與path相切
  • timingFunctions:動(dòng)畫執(zhí)行效果數(shù)組,CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn),有kCAMediaTimingFunctionLinear、kCAMediaTimingFunctionEaseIn、kCAMediaTimingFunctionEaseOut、kCAMediaTimingFunctionEaseInEaseOut、kCAMediaTimingFunctionDefault等選項(xiàng)|
  • calculationMode:關(guān)鍵幀時(shí)間計(jì)算方法,每幀動(dòng)畫之間如何過(guò)渡,類似與UIView的keyframeAnimation。有kCAAnimationLinear、kCAAnimationDiscrete、** kCAAnimationPaced kCAAnimationCubic、 kCAAnimationCubicPaced**等選項(xiàng)
    不同calculationMode過(guò)渡示意圖
搖一搖
        //搖一搖
        let shakeAnimation = CAKeyframeAnimation(keyPath: "transform.rotation")
        //設(shè)置晃動(dòng)角度
        let angle = M_PI_4 / 2
        //設(shè)置關(guān)鍵幀動(dòng)畫的值
        shakeAnimation.values = [angle,-angle,angle]
        //設(shè)置關(guān)鍵幀動(dòng)畫每幀的執(zhí)行時(shí)間,這里不設(shè)置也行,默認(rèn)平均分配時(shí)間
        //shakeAnimation.keyTimes = [NSNumber(double: 0), NSNumber(double: 0.5), NSNumber(double: 1)]
        //設(shè)置動(dòng)畫重復(fù)次數(shù),默認(rèn)為1次
        shakeAnimation.repeatCount = MAXFLOAT
        //設(shè)置動(dòng)畫執(zhí)行效果
        //shakeAnimation.timingFunctions = [CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn)]
        //設(shè)置相鄰動(dòng)畫過(guò)渡方式
        //shakeAnimation.calculationMode = kCAAnimationCubic
        //添加動(dòng)畫
        view1.layer.addAnimation(shakeAnimation, forKey: nil)
貝賽爾曲線畫“M”
    //創(chuàng)建貝賽爾曲線
        let path = UIBezierPath()
        //設(shè)置動(dòng)畫的執(zhí)行路徑為一個(gè)M的形狀
        path.moveToPoint(CGPoint(x: 40, y: 300))
        path.addLineToPoint(CGPoint(x: 80, y: 150))
        path.addLineToPoint(CGPoint(x: 120, y: 300))
        path.addLineToPoint(CGPoint(x: 160, y: 150))
        path.addLineToPoint(CGPoint(x: 200, y: 300))
        let bezierAnimation = CAKeyframeAnimation(keyPath: "position")
        //由于CAKeyframeAnimation的path為CGPath,所以這里要轉(zhuǎn)換一次
        bezierAnimation.path = path.CGPath
        //設(shè)置動(dòng)畫時(shí)間
        bezierAnimation.duration = 4
        //自動(dòng)旋轉(zhuǎn)layer角度與path相切
        bezierAnimation.rotationMode = kCAAnimationRotateAuto
        //設(shè)置動(dòng)畫重復(fù)次數(shù)
        bezierAnimation.repeatCount = MAXFLOAT
        //設(shè)置自動(dòng)逆向
        bezierAnimation.autoreverses = true
        view2.layer.addAnimation(bezierAnimation, forKey: nil)
普通路徑畫圓
        let circlePath = CGPathCreateMutable()
        CGPathAddEllipseInRect(circlePath, nil, CGRect(x: 375/2, y: 667/2, width: 100, height: 100))
        let circleAnimation = CAKeyframeAnimation(keyPath: "position")
        circleAnimation.path = circlePath
        circleAnimation.duration = 2
        circleAnimation.repeatCount = MAXFLOAT
        view3.layer.addAnimation(circleAnimation, forKey: nil)
縮放
        let scaleAnimation = CAKeyframeAnimation(keyPath: "transform.scale")
        scaleAnimation.values = [0.0, 0.4, 0.8, 1.2, 1.6, 1.2, 0.8, 0.4, 0.0]
        scaleAnimation.duration = 2
        scaleAnimation.autoreverses = true
        scaleAnimation.repeatCount = MAXFLOAT
        view4.layer.addAnimation(scaleAnimation, forKey: nil)

動(dòng)畫效果圖:


結(jié)語(yǔ)

簡(jiǎn)單的介紹了CABasicAnimation和CAKeyframeAnimation的使用方法,希望對(duì)看這篇文章的你有些幫助。很多有趣的動(dòng)畫其實(shí)就是將普通動(dòng)畫用到極致,這就需要我們多動(dòng)手去做,多動(dòng)腦去想。

最后編輯于
?著作權(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)容