【问题标题】:Pause and resume CABasicAnimation for Loading Screen?暂停和恢复加载屏幕的 CABasicAnimation?
【发布时间】:2013-04-03 14:21:11
【问题描述】:

我已经实现了一个 LoadingLayer 类,它有一些动画元素(准确地说是 2 个),这些元素使用 CABasicAnimation 进行动画处理。现在,这个加载屏幕视图在整个应用程序中持续存在。隐藏视图会停止所有动画吗?或者让我换个说法:我需要担心很多内存还是可能导致滞后?我尝试使用-pauseLayer:-resumeLayer: 方法,但由于我的应用程序中的多线程,它们导致了一些问题。因此,是否可以隐藏和显示加载屏幕并且其动画一直在运行?

【问题讨论】:

    标签: ios objective-c cabasicanimation


    【解决方案1】:

    https://developer.apple.com/library/content/qa/qa1673/_index.html

    -(void)pauseLayer:(CALayer*)layer
    {
        CFTimeInterval pausedTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil];
        layer.speed = 0.0;
        layer.timeOffset = pausedTime;
    }
    
    -(void)resumeLayer:(CALayer*)layer
    {
        CFTimeInterval pausedTime = [layer timeOffset];
        layer.speed = 1.0;
        layer.timeOffset = 0.0;
        layer.beginTime = 0.0;
        CFTimeInterval timeSincePause = [layer convertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime;
        layer.beginTime = timeSincePause;
    }
    

    【讨论】:

    • 我有一个非常相似的实现,但你的工作,谢谢!
    • 好吧,不,实际上我有完全相同的实现。但现在我知道为什么它不时停止工作了。每当应用程序进入后台并且我重新启动它时,动画就不会再次恢复。知道是什么原因造成的吗?
    • 尝试清除动画并在 didBeomceActive 上读取它们
    • 我认为这些动画可能会因为 ARC 而被清除。但是,我只是在调用 -viewWillAppear: 时重新添加它们,并在调用 -viewWillDisappear: 时清除它们。
    【解决方案2】:

    这是Nico's答案的swift 3版本。

    希望有所帮助!

    fileprivate func pauseLayer(layer: CALayer) {
        let pausedTime = layer.convertTime(CACurrentMediaTime(), from: nil)
        layer.speed = 0.0
        layer.timeOffset = pausedTime
    }
    
    fileprivate func resumeLayer(layer: CALayer) {
        let pausedTime = layer.timeOffset
        layer.speed = 1.0
        layer.timeOffset = 0.0
        layer.beginTime = 0.0
        let timeSincePause = layer.convertTime(CACurrentMediaTime(), from: nil) - pausedTime
        layer.beginTime = timeSincePause
    }
    

    【讨论】:

      【解决方案3】:

      如果视图被隐藏(不可见或根本不在界面中),则它不是渲染树的一部分。

      但是,为什么不简单地在嵌入了该层的视图控制器离开界面时停止动画(viewDidDisappear)?只需将图层告诉removeAllAnimations。如果需要,然后在 viewWillAppear? 中重新创建动画?

      【讨论】:

        【解决方案4】:

        Nico's answer for modifying speed 扩展到任何变量:

        extension CALayer {
            func udpate(speed newSpeed: Float) {
                let newSpeed = newSpeed == 0 ? 1e-6 : newSpeed
                let triggerTime = self.convertTime(CACurrentMediaTime(), from: nil)
                let offset = self.timeOffset
                let begin = self.beginTime
                let speed = self.speed
                self.beginTime = (triggerTime - offset) / Double(speed) + begin
                self.timeOffset = triggerTime
                self.speed = newSpeed
            }
        }
        

        如果您愿意以交互方式更改图层动画速度,请使用此方法。如果你想完全停止图层,你应该使用 Nico 的答案,尽管使用 speed=0.0 的这种方法实际上需要大约 11 天 才能完成动画,并且在 1 小时内动画将进行大约 @987654324 @

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-01-03
          • 2012-11-26
          • 2013-07-19
          • 2015-07-28
          • 2014-12-03
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多