LoadingAnimation Walk
最左邊的點從上方拋擲最右邊,然後整體向左移動,循環動畫。
Loading View
將點平均分布在一個水平面上。
1 2 3 4 5 6 7 8 9 10 11 |
for i in 0 ..< dotCount { let dotLayer = CAShapeLayer() dotLayer.bounds = CGRect(x: 0, y: 0, width: lineWidth, height: lineWidth) dotLayer.path = UIBezierPath(ovalIn: dotLayer.bounds).cgPath dotLayer.position = CGPoint(x: CGFloat(i) * bounds.width / CGFloat(dotCount - 1), y: bounds.height / 2.0) dotLayer.fillColor = UIColor.white.cgColor dotLayer.strokeColor = UIColor.white.cgColor layer.addSublayer(dotLayer) dotGroup.append(dotLayer) } |
動畫分析
最左側的點負責做從上方拋擲最右邊的動畫,其他的點負責向左平移的動畫,所有的點同時並重複做動畫。
視覺上看起來水平面上有個傳送帶在移動這些點,每次輪到最左邊以後就拋到最右邊。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
// Animation - move dot1 to right let dotLayer1 = dotGroup[0] let pathAnimation = CAKeyframeAnimation(keyPath: "position") pathAnimation.path = UIBezierPath(arcCenter: CGPoint(x: bounds.width / 2.0, y: bounds.height / 2.0), radius: bounds.width / 2.0, startAngle: CGFloat(Double.pi), endAngle: 0, clockwise: true).cgPath pathAnimation.calculationMode = kCAAnimationPaced pathAnimation.duration = animationDuration pathAnimation.repeatCount = Float.infinity dotLayer1.add(pathAnimation, forKey: "pathAnimation") // Animation - move other dots to left for i in 1 ..< dotCount { let dotLayer = dotGroup[i] let positionAnimation = CABasicAnimation(keyPath: "position.x") positionAnimation.toValue = dotLayer.position.x - bounds.width / CGFloat(dotCount - 1) positionAnimation.duration = animationDuration positionAnimation.repeatCount = Float.infinity dotLayer.add(positionAnimation, forKey: "positionAnimation") } |
Reference
- 在 Github 上有相關的 Source Code
- STLoadingGroup