首页 > 解决方案 > 带有 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()
        }
    }
}
}

标签: swiftbackgroundswiftui

解决方案


我可能错了,但记录的错误看起来像 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)
}

推荐阅读