在項目當(dāng)中經(jīng)常看到一些非常好看的動畫,于是乎自己也利用了一下業(yè)余時間把這塊東西整理
先看一個簡單的結(jié)構(gòu)圖

animation.png
CAAnimation本身不能使用,需要使用他的子類。
- CAPropertyAnimation 屬性動畫 (本身也不能使用,要使用它的子類)
- CAAnimationGroup 組動畫
- CATransition 轉(zhuǎn)場動畫,系統(tǒng)就是使用在這個來做轉(zhuǎn)場動畫效果處理的
一、CAPropertyAnimation之CABaseAnimaiton
因為CAAnimaiton是對Layer進行動畫,屬性動畫顧名思義就是對Layer的屬性進行動畫。
在CABaseAnimation中常用的屬性介紹:

屬性介紹.png
具有動畫效果的KeyPath有

圖片.png
代碼如下:
class func baseAnimationWithKeyPath(_ path : String , fromValue : Any? , toValue : Any?, duration : CFTimeInterval, repeatCount : Float? , timingFunction : String?) -> CABasicAnimation{
let animate = CABasicAnimation(keyPath: path)
//起始值
animate.fromValue = fromValue;
//變成什么,或者說到哪個值
animate.toValue = toValue
//所改變屬性的起始改變量 比如旋轉(zhuǎn)360°,如果該值設(shè)置成為0.5 那么動畫就從180°開始
// animate.byValue =
//動畫結(jié)束是否停留在動畫結(jié)束的位置
// animate.isRemovedOnCompletion = false
//動畫時長
animate.duration = duration
//重復(fù)次數(shù) Float.infinity 一直重復(fù) OC:HUGE_VALF
animate.repeatCount = repeatCount ?? 0
//設(shè)置動畫在該時間內(nèi)重復(fù)
// animate.repeatDuration = 5
//延時動畫開始時間,使用CACurrentMediaTime() + 秒(s)
// animate.beginTime = CACurrentMediaTime() + 2;
//設(shè)置動畫的速度變化
/*
kCAMediaTimingFunctionLinear: String 勻速
kCAMediaTimingFunctionEaseIn: String 先慢后快
kCAMediaTimingFunctionEaseOut: String 先快后慢
kCAMediaTimingFunctionEaseInEaseOut: String 兩頭慢,中間快
kCAMediaTimingFunctionDefault: String 默認(rèn)效果和上面一個效果極為類似,不易區(qū)分
*/
animate.timingFunction = CAMediaTimingFunction(name: timingFunction ?? kCAMediaTimingFunctionEaseInEaseOut)
//動畫在開始和結(jié)束的時候的動作
/*
kCAFillModeForwards 保持在最后一幀,如果想保持在最后一幀,那么isRemovedOnCompletion應(yīng)該設(shè)置為false
kCAFillModeBackwards 將會立即執(zhí)行第一幀,無論是否設(shè)置了beginTime屬性
kCAFillModeBoth 該值是上面兩者的組合狀態(tài)
kCAFillModeRemoved 默認(rèn)狀態(tài),會恢復(fù)原狀
*/
animate.fillMode = kCAFillModeBoth
//動畫結(jié)束時,是否執(zhí)行逆向動畫
// animate.autoreverses = true
return animate
}
實例圖:

aniChange.gif

aniPosition.gif

aniRotation.gif

aniScale.gif

aniSize.gif
二、CAPropertyAnimation之CAKeyframeAnimation
關(guān)鍵幀動畫屬性介紹
圖片.png
代碼
class func keyFrameAnimationWithKeyPath(_ keyPath : String , values : [Any]? , keyTimes : [NSNumber]? , path : CGPath? , duration : CFTimeInterval , cacluationMode : String , rotationMode : String?) -> CAKeyframeAnimation{
let keyFrame = CAKeyframeAnimation(keyPath: keyPath)
//由關(guān)鍵幀(關(guān)鍵值),通過關(guān)鍵幀對應(yīng)的值執(zhí)行動畫
keyFrame.values = values
//當(dāng)設(shè)置了path之后,values就沒有效果了
keyFrame.path = path
//計算模式
/*
`discrete', 離散的,不進行插值運算
`linear', 線性插值
`paced', 節(jié)奏動畫,自動計算動畫的運動時間,是的動畫均勻運行,而不是根據(jù)keyTimes的值進行動畫,設(shè)置這個模式keyTimes和timingFunctions無效
`cubic' 對關(guān)鍵幀為坐標(biāo)點的關(guān)鍵幀進行圓滑曲線相連后插值計算,需要設(shè)置timingFunctions。還可以通過tensionValues,continueityValues,biasValues來進行調(diào)整自定義
`cubicPaced' 結(jié)合了paced和cubic動畫效果
*/
keyFrame.calculationMode = cacluationMode
//旋轉(zhuǎn)模式
/*
`auto' = kCAAnimationRotateAuto 根據(jù)路徑自動旋轉(zhuǎn)
`autoReverse' = kCAAnimationRotateAutoReverse 根據(jù)路徑自動翻轉(zhuǎn)
*/
keyFrame.rotationMode = rotationMode
/*
用來區(qū)分動畫的分割時機。值區(qū)間為0.0 ~ 1.0 ,數(shù)組中的后一個值比前一個大或者相等,最好的是和Values或者Path控制的值對應(yīng)
這個屬性只在 calculationMode = linear/discrete/cubic是被使用
*/
keyFrame.keyTimes = keyTimes
//動畫時長
keyFrame.duration = duration
return keyFrame
}
效果:

aniKeyFrame.gif
三、組動畫CAAnimationGroup
組動畫是就是添加多個動畫,同時產(chǎn)生動畫效果
這個的屬性比較簡單:
- open var animations: [CAAnimation]?
代碼
//創(chuàng)建動畫組
let layerGroup = CAAnimationGroup()
//添加動畫
layerGroup.animations = [shadowColorAni,shadowOffsetAni,shadowRadiusAni,shadowOpacityAni,positionYAni,boundsAni]
//重復(fù)次數(shù)
layerGroup.repeatCount = Float.infinity
//動畫時間
layerGroup.duration = 1.8
//翻轉(zhuǎn)
layerGroup.autoreverses = true
//把層添加進去
view.layer.insertSublayer(shapeLayer, at : 0)
//添加動畫
shapeLayer.add(layerGroup, forKey: "layerGroup")
效果:
aniGroup.gif
四、CATransition轉(zhuǎn)場動畫
屬性介紹

圖片.png
代碼
class func transitionAnimationWith(duration : CFTimeInterval, type : String , subtype : String? , startProgress : Float , endProgress : Float) -> CATransition{
let transitionAni = CATransition()
//轉(zhuǎn)場類型
transitionAni.type = type
/*
kCATransitionFromTop 從頂部轉(zhuǎn)場
kCATransitionFromBottom 從底部轉(zhuǎn)場
kCATransitionFromLeft 從左邊轉(zhuǎn)場
kCATransitionFromRight 從右邊轉(zhuǎn)場
*/
transitionAni.subtype = subtype ?? kCATransitionFromLeft
//動畫開始的進度
transitionAni.startProgress = startProgress
//動畫結(jié)束的進度
transitionAni.endProgress = endProgress
//動畫的時間
transitionAni.duration = duration
return transitionAni
}
效果

aniTransition.gif
五、IOS9之后的 Spring動畫
屬性:

圖片.png
代碼
class func springAnimationWithPath(_ path : String , mass : CGFloat , stiffness : CGFloat , damping : CGFloat , fromValue : Any? , toValue : Any) -> CASpringAnimation{
let springAni = CASpringAnimation(keyPath: path)
//質(zhì)量:影響圖層運動時的彈簧慣性,質(zhì)量越大,彈簧的拉伸和壓縮的幅度越大,動畫的速度變慢,且波動幅度變大
springAni.mass = mass
//剛度:越大動畫越快
springAni.stiffness = stiffness
//阻尼:越大停止越快
springAni.damping = damping
//初始速率
springAni.initialVelocity = 0
//初始值
springAni.fromValue = fromValue
//結(jié)束值
springAni.toValue = toValue
print("動畫停止預(yù)估時間" + "\(springAni.settlingDuration)")
springAni.duration = springAni.settlingDuration
return springAni
}
效果:

aniSpring.gif
六、綜合實例
動畫代碼全部都在Git上面

aniDrawline.gif

aniFire1.gif

aniFire2.gif

aniLogin.gif

aniWaveLine.gif
-
DEMO地址
-
如果覺得有用,用star砸死我吧

圖片.png

