一個小小的動畫,太陽公公上山又下山。先上效果圖。

用 lipecap 錄的gif效果有點卡頓。好吧,說下如何實現的。
首先在一個大圓內先計算出內切九邊形各個頂點的位置,接着連接相應的頂點變成一個九角星太陽的九條光芒,然后在九角星的中心畫一個圈形的Layer,這樣就大致畫好了大陽的形狀。
新建一個叫SunView的文件繼承自UIView,然后在init方法內添加一個addSunLayer()的方法。並在里面添加以下方內容
class SunView: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
addSunLayer()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
}
在addSunLayer()方法內添加繪制九角星的代碼:
let ninePolyganPath:UIBezierPath = UIBezierPath()
//大圓的半徑
let radius:CGFloat = self.frame.size.width / 2
//九角星各個頂點的位置
var anglePoints:Dictionary<String,CGPoint> = Dictionary<String,CGPoint>()
//第一個頂點的位置,最右邊中間那個點
let firstPoint:CGPoint = CGPoint(x: bounds.width, y: bounds.width / 2)
anglePoints["0"] = firstPoint
ninePolyganPath.moveToPoint(firstPoint)
for i in 1..<9 {
//將圓分成9份,每一份的大小為40度
let angle = Double(i) * 40.0
//算出相應角度的三角函數值
let rateSin:CGFloat = sin(CGFloat(angle / 180 * M_PI))
let rateCos:CGFloat = cos(CGFloat(angle / 180 * M_PI))
let x:CGFloat = radius * rateCos + radius
let y:CGFloat = radius * rateSin + radius
anglePoints[String(i)] = CGPoint(x: x, y: y)
}
//連接相應的九個點,使之成為九角星
ninePolyganPath.addLineToPoint(anglePoints["4"]!)
ninePolyganPath.addLineToPoint(anglePoints["8"]!)
ninePolyganPath.addLineToPoint(anglePoints["3"]!) ninePolyganPath.addLineToPoint(anglePoints["7"]!) ninePolyganPath.addLineToPoint(anglePoints["2"]!)
ninePolyganPath.addLineToPoint(anglePoints["6"]!)
ninePolyganPath.addLineToPoint(anglePoints["1"]!)
ninePolyganPath.addLineToPoint(anglePoints["5"]!)
ninePolyganPath.closePath()
let ninePolyganLayer:CAShapeLayer = CAShapeLayer()
ninePolyganLayer.fillColor = UIColor.yellowColor().CGColor
ninePolyganLayer.strokeColor = UIColor.yellowColor().CGColor
ninePolyganLayer.lineWidth = 5
ninePolyganLayer.path = ninePolyganPath.CGPath
self.layer.addSublayer(ninePolyganLayer)
在ViewContoller文件內添加以下代碼:
let sunView = SunView(frame: CGRect(x: 100, y: 100, width: 100, height: 100))
self.view.addSubview(sunView)
此時九角星就做好了,運行的效果如下:

接着要在九角星的中星心位置添加一個圓,做為太陽中心。添加一個計算屬性,一個鉅形的內切圓路徑。
var sunCirclePath:UIBezierPath {
return UIBezierPath(ovalInRect: CGRect(x: self.frame.size.width * 0.3 / 2, y: self.frame.size.height * 0.3 / 2, width: self.frame.size.width - self.frame.size.width * 0.3, height: self.frame.size.height - self.frame.size.height * 0.3))
}
接着在addSunLayer方法內添加以下內容:
let sunLayer:CAShapeLayer = CAShapeLayer()
sunLayer.path = sunCirclePath.CGPath
sunLayer.lineWidth = 5
sunLayer.fillColor = UIColor.yellowColor().CGColor
sunLayer.strokeColor = UIColor.colorWithHexString("#eecc00").CGColor
self.layer.addSublayer(sunLayer)
//讓太陽轉動起來
let animation:CABasicAnimation = CABasicAnimation(keyPath: "transform.rotation")
animation.fromValue = 0.0
animation.toValue = 2 * M_PI
animation.duration = 5
animation.repeatCount = HUGE
layer.addAnimation(animation, forKey: nil)
並將上面ninePolyganLayer添加到圖層的代碼做如下修改。
self.layer.insertSublayer(ninePolyganLayer, below: sunLayer)
//self.layer.addSublayer(ninePolyganLayer)
此時運行效果如下:

最后就是讓sunView按着指定的路徑運行就可以了。回到ViewController文件內,添加以下計算路徑屬性,畫出一條弧形路徑,然后讓太陽按着這個路徑移動。
var sunrisePath:UIBezierPath {
let path:UIBezierPath = UIBezierPath()
path.moveToPoint(CGPoint(x: 0, y: 160))
path.addQuadCurveToPoint(CGPoint(x: self.view.frame.size.width, y: 160), controlPoint: CGPoint(x: self.view.frame.size.width / 2, y: 60))
//path.closePath() //這個不能用,
return path
}
添加以下動畫代碼
let sunriseAnimation:CAKeyframeAnimation = CAKeyframeAnimation(keyPath: "position") sunriseAnimation.path = sunrisePath.CGPath sunriseAnimation.duration = 3
sunriseAnimation.calculationMode = kCAAnimationPaced sunriseAnimation.fillMode = kCAFillModeForwards sunriseAnimation.repeatCount = HUGE sunriseAnimation.removedOnCompletion = false sunView.layer.addAnimation(sunriseAnimation, forKey: nil)
這樣就完成了。以上僅供參考,還請大家多提意見。
