雷達(dá)動(dòng)畫,或者說水波動(dòng)畫,就是用的一個(gè)動(dòng)畫組。效果如下:

Mar-28-2018 19-19-01.gif
全部代碼,除了兩個(gè)按鈕是SB上的。留有詳細(xì)注釋,留作以后參考。其余復(fù)制可用:
import UIKit
class ViewController: UIViewController {
private let radarAnimation = "radarAnimation"
private var animationLayer: CALayer?
private var animationGroup: CAAnimationGroup?
private var opBtn: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
let first = makeRadarAnimation(showRect: CGRect(x: 120, y: 100, width: 100, height: 100), isRound: true)
view.layer.addSublayer(first)
opBtn = UIButton(frame: CGRect(x: 100, y: 450, width: 80, height: 80))
opBtn.backgroundColor = UIColor.red
opBtn.clipsToBounds = true
opBtn.setTitle("Hsu", for: .normal)
opBtn.layer.cornerRadius = 10
view.addSubview(opBtn)
let second = makeRadarAnimation(showRect: opBtn.frame, isRound: false)
view.layer.insertSublayer(second, below: opBtn.layer)
}
@IBAction func startAction(_ sender: UIButton) {
animationLayer?.add(animationGroup!, forKey: radarAnimation)
}
@IBAction func stopAction(_ sender: UIButton) {
animationLayer?.removeAnimation(forKey: radarAnimation)
}
private func makeRadarAnimation(showRect: CGRect, isRound: Bool) -> CALayer {
// 1. 一個(gè)動(dòng)態(tài)波
let shapeLayer = CAShapeLayer()
shapeLayer.frame = showRect
// showRect 最大內(nèi)切圓
if isRound {
shapeLayer.path = UIBezierPath(ovalIn: CGRect(x: 0, y: 0, width: showRect.width, height: showRect.height)).cgPath
} else {
// 矩形
shapeLayer.path = UIBezierPath(roundedRect: CGRect(x: 0, y: 0, width: showRect.width, height: showRect.height), cornerRadius: 10).cgPath
}
shapeLayer.fillColor = UIColor.orange.cgColor
// 默認(rèn)初始顏色透明度
shapeLayer.opacity = 0.0
animationLayer = shapeLayer
// 2. 需要重復(fù)的動(dòng)態(tài)波,即創(chuàng)建副本
let replicator = CAReplicatorLayer()
replicator.frame = shapeLayer.bounds
replicator.instanceCount = 4
replicator.instanceDelay = 1.0
replicator.addSublayer(shapeLayer)
// 3. 創(chuàng)建動(dòng)畫組
let opacityAnimation = CABasicAnimation(keyPath: "opacity")
opacityAnimation.fromValue = NSNumber(floatLiteral: 1.0) // 開始透明度
opacityAnimation.toValue = NSNumber(floatLiteral: 0) // 結(jié)束時(shí)透明底
let scaleAnimation = CABasicAnimation(keyPath: "transform")
if isRound {
scaleAnimation.fromValue = NSValue.init(caTransform3D: CATransform3DScale(CATransform3DIdentity, 0, 0, 0)) // 縮放起始大小
} else {
scaleAnimation.fromValue = NSValue.init(caTransform3D: CATransform3DScale(CATransform3DIdentity, 1.0, 1.0, 0)) // 縮放起始大小
}
scaleAnimation.toValue = NSValue.init(caTransform3D: CATransform3DScale(CATransform3DIdentity, 1.5, 1.5, 0)) // 縮放結(jié)束大小
let animationGroup = CAAnimationGroup()
animationGroup.animations = [opacityAnimation, scaleAnimation]
animationGroup.duration = 3.0 // 動(dòng)畫執(zhí)行時(shí)間
animationGroup.repeatCount = HUGE // 最大重復(fù)
animationGroup.autoreverses = false
self.animationGroup = animationGroup
shapeLayer.add(animationGroup, forKey: radarAnimation)
return replicator
}
}