CAPropertyAnimation也是一個(gè)抽象類(lèi),自身并不能對(duì)layer進(jìn)行動(dòng)畫(huà)操作菜循,需要其子類(lèi)CABasicAnimation和CAKeyframeAnimation來(lái)實(shí)現(xiàn)動(dòng)畫(huà)操作翘地。
屬性解讀:
屬性 | 描述 |
---|---|
keyPath | 指定接收層動(dòng)畫(huà)的關(guān)鍵路徑(入門(mén)篇提供了部分keyPath,敬請(qǐng)參考) |
cumulative | 下一次動(dòng)畫(huà)執(zhí)行是否接著剛才的動(dòng)畫(huà)债朵,默認(rèn)為false |
additive | 如何處理多個(gè)動(dòng)畫(huà)在同一時(shí)間段執(zhí)行的結(jié)果子眶,若為true,同一時(shí)間段的動(dòng)畫(huà)合成為一個(gè)動(dòng)畫(huà)序芦,默認(rèn)為false臭杰。(使用 CAKeyframeAnimation 時(shí)必須將該屬性指定為 true ,否則不會(huì)出現(xiàn)期待的結(jié)果) |
一谚中、CABasicAnimation(基礎(chǔ)動(dòng)畫(huà))
該子類(lèi)中有三個(gè)屬性:fromValue渴杆、byValue、toValue宪塔,主要用來(lái)操作縮放磁奖、平移和旋轉(zhuǎn)等簡(jiǎn)單動(dòng)畫(huà)。隨著動(dòng)畫(huà)的進(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)畫(huà)效果穴亏!
旋轉(zhuǎn)動(dòng)畫(huà)
//默認(rèn)是繞著z軸旋轉(zhuǎn),也可指定繞某個(gè)軸旋轉(zhuǎn):transform.rotation.x
let animation = CABasicAnimation(keyPath: "transform.rotation")
//只設(shè)置toValue重挑,動(dòng)畫(huà)會(huì)在圖層對(duì)應(yīng)當(dāng)前值與toValue之間漸變
animation.toValue = M_PI * 2
//設(shè)置動(dòng)畫(huà)重復(fù)次數(shù)
animation.repeatCount = MAXFLOAT
//設(shè)置動(dòng)畫(huà)執(zhí)行時(shí)間
animation.duration = 1
//添加動(dòng)畫(huà)到layer
redView.layer.addAnimation(animation, forKey: nil)
縮放動(dòng)畫(huà)
//transform.scale默認(rèn)是x,y,z三個(gè)方向同時(shí)同比例縮放嗓化,也可指定某一個(gè)方向縮放
let animation = CABasicAnimation(keyPath: "transform.scale")
//只設(shè)置fromValue動(dòng)畫(huà)會(huì)在fromValue與圖層對(duì)應(yīng)當(dāng)前值之前漸變
animation.fromValue = -CGRectGetWidth(view.bounds)
//設(shè)置動(dòng)畫(huà)重復(fù)次數(shù)
animation.repeatCount = MAXFLOAT
//設(shè)置動(dòng)畫(huà)執(zhí)行時(shí)間
animation.duration = 1
//添加動(dòng)畫(huà)到layer,添加動(dòng)畫(huà)的key可以為nil谬哀,也可以為任意值刺覆,是用來(lái)在CAAnimation協(xié)議方法中區(qū)分不同動(dòng)畫(huà),相當(dāng)于UIView的tag
greenView.layer.addAnimation(animation, forKey: nil)
平移動(dòng)畫(huà):
//keyPath可設(shè)置為x玻粪,y隅津,z在對(duì)應(yīng)方向平移或者直接寫(xiě)成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)畫(huà)重復(fù)次數(shù)
animation.repeatCount = MAXFLOAT
//設(shè)置動(dòng)畫(huà)執(zhí)行時(shí)間
animation.duration = 1
//添加動(dòng)畫(huà)到layer
blueView.layer.addAnimation(animation, forKey: nil)
動(dòng)畫(huà)效果圖:
二劲室、CAKeyframeAnimation
CALayer的關(guān)鍵幀動(dòng)畫(huà)與UIView的關(guān)鍵幀動(dòng)畫(huà)類(lèi)似伦仍,UIView的動(dòng)畫(huà)可以看做是核心動(dòng)畫(huà)的簡(jiǎn)單封裝。關(guān)鍵幀動(dòng)畫(huà)的值可以指定為一個(gè)值數(shù)組或者一個(gè)路徑很洋,和CABasicAnimation不同的是充蓝,關(guān)鍵幀動(dòng)畫(huà)在同一時(shí)間內(nèi)對(duì)同一layer可以做多種不同動(dòng)畫(huà),并且可以控制各動(dòng)畫(huà)的執(zhí)行節(jié)奏喉磁。CAKeyframeAnimation常用的兩個(gè)屬性是values和duration谓苟,這兩個(gè)屬性就可以簡(jiǎn)單的設(shè)置動(dòng)畫(huà)了,其余屬性提供了更加細(xì)致化协怒,更加強(qiáng)大的功能涝焙!
屬性解讀:
- values:關(guān)鍵幀動(dòng)畫(huà)值的數(shù)組,當(dāng)path為nil時(shí)設(shè)置有效孕暇,否則優(yōu)先選擇屬性path做動(dòng)畫(huà)
- path:動(dòng)畫(huà)執(zhí)行的點(diǎn)路徑(通過(guò)Core Graphics提供的API來(lái)繪制路徑)仑撞,設(shè)置了path诉瓦,values將被忽略
- keyTimes:關(guān)鍵幀動(dòng)畫(huà)每幀動(dòng)畫(huà)開(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)畫(huà)執(zhí)行時(shí)間平均(公式:總時(shí)間/(總幀數(shù)-1))骚亿。例如曲秉,如果你指定了一個(gè)5幀采蚀,10秒的動(dòng)畫(huà),那么每幀的時(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)畫(huà)執(zhí)行效果數(shù)組,CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn),有kCAMediaTimingFunctionLinear矢洲、kCAMediaTimingFunctionEaseIn璧眠、kCAMediaTimingFunctionEaseOut、kCAMediaTimingFunctionEaseInEaseOut读虏、kCAMediaTimingFunctionDefault等選項(xiàng)|
- calculationMode:關(guān)鍵幀時(shí)間計(jì)算方法责静,每幀動(dòng)畫(huà)之間如何過(guò)渡,類(lèi)似與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)畫(huà)的值
shakeAnimation.values = [angle,-angle,angle]
//設(shè)置關(guān)鍵幀動(dòng)畫(huà)每幀的執(zhí)行時(shí)間嵌赠,這里不設(shè)置也行,默認(rèn)平均分配時(shí)間
//shakeAnimation.keyTimes = [NSNumber(double: 0), NSNumber(double: 0.5), NSNumber(double: 1)]
//設(shè)置動(dòng)畫(huà)重復(fù)次數(shù)熄赡,默認(rèn)為1次
shakeAnimation.repeatCount = MAXFLOAT
//設(shè)置動(dòng)畫(huà)執(zhí)行效果
//shakeAnimation.timingFunctions = [CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn)]
//設(shè)置相鄰動(dòng)畫(huà)過(guò)渡方式
//shakeAnimation.calculationMode = kCAAnimationCubic
//添加動(dòng)畫(huà)
view1.layer.addAnimation(shakeAnimation, forKey: nil)
貝賽爾曲線(xiàn)畫(huà)“M”
//創(chuàng)建貝賽爾曲線(xiàn)
let path = UIBezierPath()
//設(shè)置動(dòng)畫(huà)的執(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)畫(huà)時(shí)間
bezierAnimation.duration = 4
//自動(dòng)旋轉(zhuǎn)layer角度與path相切
bezierAnimation.rotationMode = kCAAnimationRotateAuto
//設(shè)置動(dòng)畫(huà)重復(fù)次數(shù)
bezierAnimation.repeatCount = MAXFLOAT
//設(shè)置自動(dòng)逆向
bezierAnimation.autoreverses = true
view2.layer.addAnimation(bezierAnimation, forKey: nil)
普通路徑畫(huà)圓
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)畫(huà)效果圖:
結(jié)語(yǔ)
簡(jiǎn)單的介紹了CABasicAnimation和CAKeyframeAnimation的使用方法,希望對(duì)看這篇文章的你有些幫助彼硫。很多有趣的動(dòng)畫(huà)其實(shí)就是將普通動(dòng)畫(huà)用到極致炊豪,這就需要我們多動(dòng)手去做,多動(dòng)腦去想拧篮。