Swift 5 CAKeyframeAnimation - 应用移至后台后恢复图层动画
Swift 5 CAKeyframeAnimation - Resume layer animation after app moved to bacground
我想显示小指示条(用于声音)
这里是代码:
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 { [=11=].alpha = 0 }
}
private func pauseAnimation() {
bars.forEach {
[=11=].layer.speed = 0
[=11=].transform = CGAffineTransform(scaleX: 1, y: 0.1)
}
}
private func playAnimation() {
bars.forEach {
[=11=].alpha = 1
[=11=].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")
}
}
并且工作正常。我正在使用另一个 vc..etc.
问题
当应用移至后台时,音乐播放器暂停,并在 IndicatorView
中分配 state = .pause
,但当应用返回时,用户点击播放,例如。在 IndicatorView
state = .play
playAnimation()
被调用,条形层有速度 1...但根本没有动画。
Here is a short video to describe my problem
谢谢
当应用进入后台时,CALayer 动画暂停。您可以实现在转到 bg/fg 时暂停和恢复动画的方法,但是对于您的情况,如果您将对 "addAnimation(to: b)" 的调用从设置视图移动到 "playAnimation()" 方法,则可以保证动画永远在那里。例如:
bars.forEach {
[=10=].alpha = 1
addAnimation(to: [=10=])
[=10=].layer.speed = 1
}
希望对您有所帮助:)
我想显示小指示条(用于声音)
这里是代码:
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 { [=11=].alpha = 0 }
}
private func pauseAnimation() {
bars.forEach {
[=11=].layer.speed = 0
[=11=].transform = CGAffineTransform(scaleX: 1, y: 0.1)
}
}
private func playAnimation() {
bars.forEach {
[=11=].alpha = 1
[=11=].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")
}
}
并且工作正常。我正在使用另一个 vc..etc.
问题
当应用移至后台时,音乐播放器暂停,并在 IndicatorView
中分配 state = .pause
,但当应用返回时,用户点击播放,例如。在 IndicatorView
state = .play
playAnimation()
被调用,条形层有速度 1...但根本没有动画。
Here is a short video to describe my problem
谢谢
当应用进入后台时,CALayer 动画暂停。您可以实现在转到 bg/fg 时暂停和恢复动画的方法,但是对于您的情况,如果您将对 "addAnimation(to: b)" 的调用从设置视图移动到 "playAnimation()" 方法,则可以保证动画永远在那里。例如:
bars.forEach {
[=10=].alpha = 1
addAnimation(to: [=10=])
[=10=].layer.speed = 1
}
希望对您有所帮助:)