標籤:動畫 swift cakeyframe
一.組動畫的建立
首先建立一個組動畫,也就是大小變化和透明度變化的動畫。
// 大小變化 let scaleAnimation = CAKeyframeAnimation(keyPath: "transform.scale") scaleAnimation.keyTimes = [0, 0.5, 1] scaleAnimation.values = [1, 0.4, 1] scaleAnimation.duration = duration // 透明度變化 let opacityAnimaton = CAKeyframeAnimation(keyPath: "opacity") //該屬性是一個數組,用以指定每個子路徑的時間。 opacityAnimaton.keyTimes = [0, 0.5, 1] //values屬性指明整個動畫過程中的主要畫面格點,需要注意的是,起點必須作為values的第一個值。 opacityAnimaton.values = [1, 0.3, 1] opacityAnimaton.duration = duration // 組動畫 let animation = CAAnimationGroup() //將大小變化和透明度變化的動畫加入到組動畫 animation.animations = [scaleAnimation, opacityAnimaton] //動畫的過渡效果 animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear) //動畫的期間 animation.duration = duration //設定重複次數,HUGE可看做無窮大,起到迴圈動畫的效果 animation.repeatCount = HUGE //運行一次是否移除動畫 animation.removedOnCompletion = false
需要注意的是上面的animation.timingFunction是動畫的過渡效果,裡面有這幾種,你可以根據自己的需求選擇
1. kCAMediaTimingFunctionLinear//線性
2. kCAMediaTimingFunctionEaseIn//淡入
3. kCAMediaTimingFunctionEaseOut//淡出
4. kCAMediaTimingFunctionEaseInEaseOut//淡入淡出
5. kCAMediaTimingFunctionDefault//預設
二.建立圓形圖層
// Draw circles for var i = 0; i < 8; i++ { let circle = creatCircle(angle: CGFloat(M_PI_4 * Double(i)), size: circleSize, origin: CGPoint(x: x, y: y + 50), containerSize: size, color: color) animation.beginTime = beginTime + beginTimes[i] circle.addAnimation(animation, forKey: "animation") layer.addSublayer(circle) }
這裡面是建立了八個小圓,將組動畫賦予這八個圓,並添加在這個視圖的Layer上,creatCircle 創圖層的這個方法如下
func creatCircle(# angle: CGFloat, size: CGFloat, origin: CGPoint, containerSize: CGSize, color: UIColor) -> CALayer { let radius = containerSize.width/2 let circle = createLayerWith(size: CGSize(width: size, height: size), color: color) let frame = CGRect( x: origin.x + radius * (cos(angle) + 1) - size / 2, y: origin.y + radius * (sin(angle) + 1) - size / 2, width: size, height: size) circle.frame = frame return circle }
上面angle,size,origin,containerSize,color,都是傳入的參數,-> CALayer 這個在Swift中代表的是傳回型別,這裡的傳回型別就是CALayer,不像在OC中傳回型別寫在方法的前面- (CALayer *) ...
這裡func creatCircle(# angle: CGFloat,裡面有#,代表的就是在函數(或者方法)的參數名前添加”#”,可以使該參數擁有相同的本地參數名和外部參數名。(註:在方法中,第二個及後續的參數,預設是具有和內部參數一致的外部參數名的,只有第一個參數沒有,可以使用”#”符號來強制給第一個參數添加與本地參數名一致的外部參數名,但是不推薦。)
三.建立CAShapeLayer
也就是上面的createLayerWith這個方法,如下
func createLayerWith(# size: CGSize, color: UIColor) -> CALayer { //建立CAShapeLayer,如果對CAShapeLayer比較陌生,簡單介紹下CAShapeLayer let layer: CAShapeLayer = CAShapeLayer() //建立貝茲路徑路徑(CAShapeLayer就依靠這個路徑渲染) var path: UIBezierPath = UIBezierPath() //addArcWithCenter,顧名思義就是根據中心點畫圓(OC文法的命名優越感又體現出來了0.0),這幾個參數 /** center: CGPoint 中心點 radius: CGFloat 半徑 startAngle: CGFloat 起始的弧度 endAngle: CGFloat 結束的弧度 clockwise: Bool 繪畫方向 true:順時針 false:逆時針 */ path.addArcWithCenter(CGPoint(x: size.width / 2, y: size.height / 2), radius: size.width / 2, startAngle: 0, endAngle: CGFloat(2 * M_PI), clockwise: false); //線寬,如果畫圓填充的話也可以不設定 layer.lineWidth = 2 //填充顏色,這裡也就是圓的顏色 layer.fillColor = color.CGColor //圖層背景色 layer.backgroundColor = nil //把貝茲路徑路徑設為layer的渲染路徑 layer.path = path.CGPath return layer; }
CAShapeLayer是一個通過向量圖形而不是bitmap來繪製的圖層子類。你指定諸如顏色和線寬等屬性,用CGPath來定義想要繪製的圖形,最後CAShapeLayer就自動渲染出來了。當然,你也可以用Core Graphics直接向原始的CALyer的內容中繪製一個路徑,相比直下,使用CAShapeLayer有以下一些優點:
- 渲染快速。
CAShapeLayer使用了硬體加速,繪製同一圖形會比用Core Graphics快很多。
- 高效使用記憶體。一個
CAShapeLayer不需要像普通CALayer一樣建立一個寄宿圖形(CALyer的contents屬性,如果要給contents賦值就是layer.contents = (__bridge id)image.CGImage,所以佔用記憶體大),所以無論有多大,都不會佔用太多的記憶體。
- 不會被圖層邊界剪裁掉。一個
CAShapeLayer可以在邊界之外繪製。你的圖層路徑不會像在使用Core Graphics的普通CALayer一樣被剪裁掉。
- 不會出現像素化。當你給
CAShapeLayer做3D變換時,它不像一個有寄宿圖的普通圖層一樣變得像素化。
到此,運行我們就可以看到效果了,如下
Swift實現一個簡單的載入動畫,以及動畫的詳解