问题描述
我正在使用在网上找到的扩展程序来保留我用于我的应用程序的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)
能解决问题