LoadingAnimation – 彈跳的三個點
動畫為三個點依次落下然後回到原來的位置上。
LoadingView
單個點的上下動畫通過 UIView Animation 很容易可以做到,但如果要呈現上面的動畫效果呢?
Dot
通過 UIBezierPath(ovalIn) 來畫一個圓,用白色來填充。
1 |
fileprivate let dotLayer: CAShapeLayer = CAShapeLayer() |
1 2 3 4 5 6 7 |
dotLayer.frame = CGRect(x: lineWidth / 2.0, y: (bounds.height - lineWidth) / 2.0, width: lineWidth, height: lineWidth) dotLayer.path = UIBezierPath(ovalIn: dotLayer.bounds).cgPath dotLayer.fillColor = UIColor.white.cgColor dotLayer.strokeColor = UIColor.white.cgColor dotLayer.lineCap = kCALineCapRound dotLayer.lineJoin = kCALineJoinRound dotLayer.lineWidth = lineWidth |
CAReplicatorLayer
這是一個繼承於 CALayer 的容器,我們將 dotLayer 加入到 subLayer 以後,通過CATransform3DMakeTranslation 設定邊距。
1 |
fileprivate let dotReplicatorLayer: CAReplicatorLayer = CAReplicatorLayer() |
1 2 3 4 5 |
dotReplicatorLayer.addSublayer(dotLayer) dotReplicatorLayer.instanceCount = dotCount dotReplicatorLayer.instanceDelay = animationDuration / Double(dotCount) dotReplicatorLayer.instanceTransform = CATransform3DMakeTranslation(bounds.width / CGFloat(dotCount), 0, 0) layer.addSublayer(dotReplicatorLayer) |
Animation
通過 CAKeyframeAnimation 對 position.y 做動畫。
1 2 3 4 5 6 7 8 9 |
let downY = bounds.midY + 10.0 let positionAnimation = CAKeyframeAnimation(keyPath: "position.y") positionAnimation.duration = animationDuration positionAnimation.beginTime = CACurrentMediaTime() + 0.5 positionAnimation.repeatCount = Float.infinity positionAnimation.values = [bounds.midY, downY, bounds.midY, bounds.midY] positionAnimation.keyTimes = [0.0, 0.33, 0.66, 1.0] dotLayer.add(positionAnimation, forKey: "positionAnimation") |
Reference
- 在 Github 上有本文相關的 Source Code