I have view to display small indicator bars (for sound)
and here it is code for this:
class IndicatorView: UIViewController {
enum AudioState {
case stop
case play
case pause
}
var state: AudioState! {
didSet {
switch state {
case .pause:
pauseAnimation()
case .play:
playAnimation()
default:
stopAnimation()
}
}
}
var numberOfBars: Int = 5
var barWidth: CGFloat = 4
var barSpacer: CGFloat = 4
var barColor: UIColor = .systemPink
private var bars: [UIView] = [UIView]()
private func stopAnimation() {
bars.forEach { $0.alpha = 0 }
}
private func pauseAnimation() {
bars.forEach {
$0.layer.speed = 0
$0.transform = CGAffineTransform(scaleX: 1, y: 0.1)
}
}
private func playAnimation() {
bars.forEach {
$0.alpha = 1
$0.layer.speed = 1
}
}
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .clear
DispatchQueue.main.async {
self.setupViews()
}
}
private func setupViews() {
for i in 0...numberOfBars - 1 {
let b = UIView()
b.backgroundColor = barColor
addAnimation(to: b)
view.addSubview(b)
bars.append(b)
b.anchor(top: view.topAnchor, leading: view.leadingAnchor, bottom: view.bottomAnchor, trailing: nil,
padding: .init(top: 0, left: CGFloat(i) * (barWidth + barSpacer), bottom: 0, right: 0),
size: .init(width: barWidth, height: 0))
}
stopAnimation()
}
private func addAnimation(to v: UIView) {
let animation = CAKeyframeAnimation()
animation.keyPath = "transform.scale.y"
animation.values = [0.1, 0.3, 0.2, 0.5, 0.8, 0.3, 0.99, 0.72, 0.3].shuffled()
animation.duration = 1
animation.autoreverses = true
animation.repeatCount = .infinity
v.layer.add(animation, forKey: "baran")
}
}
and work fine. I'm using it from another vc..etc.
When app moved to background, music player paused, and in IndicatorView
state = .pause
is assigned, but when app come back, and user tap on play eg. in IndicatorView
state = .play
playAnimation()
is called, bars layers have speed one... but no animation at all.
Here is a short video to describe my problem
Thanks
When the app goes to background the CALayer animation is paused. You could implement methods to pause and resume animation when going to bg/fg, but for your case if you move the call to "addAnimation(to: b)" from the setupviews to the "playAnimation()" method, you can guarantee the animation will always be there. ex:
bars.forEach {
$0.alpha = 1
addAnimation(to: $0)
$0.layer.speed = 1
}
Hope it helps :)