持续CABasicAnimation

问题描述

我正在使用在网上找到的扩展程序来保留我用于我的应用程序的CABasicAnimation;的代码如下。它可以正常工作,并且动画的确确实存在,因为动画层并未完全从屏幕上移除,但是我遇到的问题是,如果计时器正在运行并且倒计时动画已经开始并且用户在10点离开应用程序可以说一秒钟,然后在15秒后返回,动画从10秒继续,但实际计数在前面。

public class LayerPersistentHelper {


private var persistentAnimations: [String: CAAnimation] = [:]
private var persistentSpeed: Float = 0.0
private weak var layer: CALayer?

public init(with layer: CALayer) {
    self.layer = layer
    addNotificationObservers()
}

deinit {
    removeNotificationObservers()
}} 
private extension LayerPersistentHelper {

func addNotificationObservers() {
    let center = NotificationCenter.default
    let enterForeground = UIApplication.willEnterForegroundNotification
    let enterBackground = UIApplication.didEnterBackgroundNotification
    center.addObserver(self,selector: #selector(didBecomeActive),name: enterForeground,object: nil)
    center.addObserver(self,selector: #selector(willResignActive),name: enterBackground,object: nil)
}

func removeNotificationObservers() {
    NotificationCenter.default.removeObserver(self)
}

func persistAnimations(with keys: [String]?) {
    guard let layer = self.layer else { return }
    keys?.forEach { (key) in
        if let animation = layer.animation(forKey: key) {
            persistentAnimations[key] = animation
        }
    }
}

func restoreAnimations(with keys: [String]?) {
    guard let layer = self.layer else { return }
    keys?.forEach { (key) in
        if let animation = persistentAnimations[key] {
            layer.add(animation,forKey: key)
        }
    }
}}

@objc extension LayerPersistentHelper {
func didBecomeActive() {
    guard let layer = self.layer else { return }
    restoreAnimations(with: Array(persistentAnimations.keys))
    persistentAnimations.removeAll()
    if persistentSpeed == 1.0 { // if layer was playing before background,resume it
        layer.resumeAnimations()
    }
}

func willResignActive() {
    guard let layer = self.layer else { return }
    persistentSpeed = layer.speed
    layer.speed = 1.0 // in case layer was paused from outside,set speed to 1.0 to get all animations
    persistAnimations(with: layer.animationKeys())
    layer.speed = persistentSpeed // restore original speed
    layer.pauseAnimations()
}}


public extension CALayer {

var isAnimationsPaused: Bool {
    return speed == 0.0
}
static var timeElapsed: Double = 0

func pauseAnimations() {
    if !isAnimationsPaused {
        let currentTime = CACurrentMediaTime()
        let pausedTime = convertTime(currentTime,from: nil)
        speed = 0.0
        timeOffset = pausedTime
    }
}

func resumeAnimations() {
    let pausedTime = timeOffset
    speed = 1.0
    timeOffset = 0.0
    beginTime = 0.0
    let currentTime = CACurrentMediaTime()
    let timeSincePause = convertTime(currentTime,from: nil) - pausedTime
    beginTime = timeSincePause
}}

extension CALayer. {

static private var persistentHelperKey = "progressAnim"

func makeAnimationsPersistent() {
    var object = objc_getAssociatedObject(self,&CALayer.persistentHelperKey)
    if object == nil {
        object = LayerPersistentHelper(with: self)
        let nonatomic = objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC
        objc_setAssociatedObject(self,&CALayer.persistentHelperKey,object,nonatomic)
    }
}} 

有什么想法吗?

解决方法

如果有人遇到此问题,我发现将开始时间设置为等于

beginTime = convertTime(timeOffset,from: nil)

能解决问题

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...