swift - 带有 CAAnimation 的 Swift UIApplicationEndBackgroundTaskError
问题描述
我在我的应用程序中异步运行 CAAnimation(动画渐变)作为背景图像。当单击主页按钮(在不关闭应用程序的情况下进入主屏幕)然后您重新进入应用程序时,会出现 UIApplicationEndBackgroundTaskError。如果有人能解决这个问题,我将不胜感激。此错误的副作用是动画停止播放/暂停。谢谢!(查看下方了解更多信息)
背景代码在这里(在 SwiftUI 视图中使用)为 GradientView():
struct GradientView: UIViewControllerRepresentable {
typealias UIViewControllerType = GradientBackground
func makeUIViewController(context: UIViewControllerRepresentableContext<GradientView>) -> GradientView.UIViewControllerType {
return GradientBackground()
}
func updateUIViewController(_ uiViewController: GradientView.UIViewControllerType, context: UIViewControllerRepresentableContext<GradientView>) {
}
}
class GradientBackground : UIViewController {
let gradient = CAGradientLayer()
var gradientSet = [[CGColor]]()
var currentGradient = 0
let gradOne = #colorLiteral(red: 0.4620226622, green: 0.8382837176, blue: 1, alpha: 1).cgColor
let gradTwo = #colorLiteral(red: 1, green: 0.8323456645, blue: 0.4732058644, alpha: 1).cgColor
let gradThree = #colorLiteral(red: 0, green: 0.3285208941, blue: 0.5748849511, alpha: 1).cgColor
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
animatedGradient()
}
override func viewDidLoad() {
super.viewDidLoad()
gradientSet.append([gradOne, gradTwo])
gradientSet.append([gradTwo, gradThree])
gradientSet.append([gradThree, gradOne])
gradient.startPoint = CGPoint(x: 0, y: 0)
gradient.endPoint = CGPoint(x: 1.0, y: 1.0)
gradient.drawsAsynchronously = true
//gradient.colors = [gradOne, gradTwo]
view.layer.addSublayer(gradient)
}
override func viewDidLayoutSubviews() {
gradient.frame = view.bounds
}
func animatedGradient() {
var prevGrad: Int!
if currentGradient < gradientSet.count - 1 {
currentGradient += 1
prevGrad = currentGradient-1
}
else {
currentGradient = 0
prevGrad = gradientSet.count-1
}
let gradChangeAnim = CABasicAnimation(keyPath: "colors")
gradChangeAnim.duration = 1.5
gradChangeAnim.fromValue = gradientSet[prevGrad]
gradChangeAnim.toValue = gradientSet[currentGradient]
gradient.setValue(currentGradient, forKeyPath: "colorChange")
gradChangeAnim.delegate = self
gradient.add(gradChangeAnim, forKey: nil)
}
}
extension GradientBackground: CAAnimationDelegate {
func animationDidStart(_ anim: CAAnimation) {
//if anim.
}
func animationDidStop(_ anim: CAAnimation, finished flag: Bool) {
if flag {
if let colorChange = gradient.value(forKey: "colorChange") as? Int {
var number = colorChange + 1
if number == gradientSet.count {
number = 0
}
gradient.colors = gradientSet[number]
animatedGradient()
}
}
}
}
解决方案
我可能错了,但记录的错误看起来像 Apple 的问题。至于在应用程序重新激活时恢复动画,您可以尝试以下我在测试中使用的代码,该代码有效。
import Combine
...
class GradientBackground : UIViewController {
...
private var subscribers = [AnyCancellable]()
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
animatedGradient()
NotificationCenter.default.publisher(for: UIApplication.didEnterBackgroundNotification)
.sink { _ in
self.gradient.removeAllAnimations()
}.store(in: &subscribers)
NotificationCenter.default.publisher(for: UIApplication.didBecomeActiveNotification)
.sink { _ in
self.animatedGradient()
}.store(in: &subscribers)
}
推荐阅读
- javascript - 使用 printThis.js 重复页眉和页脚
- javascript - rebuild prompt-box behaviour
- php - Gmail API - 只允许授权用户连接
- mysql - 我应该如何将复选框移动到与显示字段相同的行?
- excel - 如何在谷歌表格的备用列中使用公式?
- java - 是否可以在 JPA 中实现 (0..n) 多对多(使用 @ManyToMany 注释)关系?
- android - 如何在棉花糖设备下添加指纹认证
- ruby - Ruby gem that allows us to handle local system's windows
- ios - UISwitch crash on value change IOS Swift
- datetime - 2016 年 9 月 14 日 19:31 的日期时间格式