繁体   English   中英

自定义CALayer动画

[英]Custom CALayer Animation

我有一个带有层的UIView,可以为我完成所有绘制。 因此,现在当我更改视图值时,它将其转发到图层。 当我处于UIView-Animaiton块中时,我希望将这一更改动画化。

所以我目前正在做什么:

class SampleView: UIView {
    var myProperty: CGFloat {
        set {
            sampleLayer.myProperty = newValue
        }
        get {
            return sampleLayer.myProperty
        }
    }

    override class var layerClass: AnyClass {
        return SampleViewLayer.self
    }

    private var sampleLayer: SampleViewLayer {
        return layer as! SampleViewLayer
    }
}

class SampleViewLayer: CALayer {
    @NSManaged public var myProperty: CGFloat

    override func draw(in ctx: CGContext) {
        // Incredible beautiful drawing is happening here depending on myProperty
    }

    override static func needsDisplay(forKey key: String) -> Bool {
        if key == "myProperty" {
            return true
        }
        return super.needsDisplay(forKey: key)
    }

    override func action(forKey event: String) -> CAAction? {

        if event == "myProperty" {

            // 1. How do I find out if the change should be animated?

            let animation = CABasicAnimation(keyPath: event)
            animation.fromValue = presentation()?.value(forKey: event)

            // 2. How do I find out the proper timingFunction as well as the proper duration?
            animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
            animation.duration = 1.0

            return animation
        }

        return super.action(forKey: event)
    }
}

我希望能够像这样制作动画:

....
instanceOfMySampleView.myProperty = 0 // inital value should be set without animation
UIView.animate(withDuration: 4, animations: {
    self.instanceOfMySampleView.myProperty = 10  // should animate to this value
})
....

因此,这两个实际问题都在我的示例代码中... 1.如何确定更改是否应采用动画处理? 那么如何找出它发生在UIView-Animation-Block内部呢?

  1. 如果是动画,如何找到持续时间和TimingFunction的合适参数?

也。 如果在代码中创建View的实例,将其myProperty值设置为初始值,然后直接执行UIViewAnimationBlock,则PresentationLayer将为nil,因此我的动画将无法正常工作...

除非自上次研究以来未进行任何更改,否则我会说您无法获得这些值。 很可惜没有提供API。

如果您对动画视图的调用是手动的(正在调用这些动画),那么我建议您将所有这些调用替换为一些自定义调用。 AnimationManager.animate(withDuration:...此方法然后调用UIView对应的方法,因此您需要用这些方法替换所有调用。完成后,您应该会看到与当前相同的结果。

现在您需要在此代码中添加逻辑以保存曲线的值,持续时间...一个基本的实现是在动画块开始时保存新值,然后在结束时将其删除(不是在完成时而是在最后一行)在动画块中)。

稍微复杂一点的系统是创建设置的堆栈(数组应该这样做),而不是单个值。 首先,您添加一个对象,最后,您只需删除它。 这样做的原因是动画调用可能被嵌套,仅删除动画设置可能还不够。 第二个原因是,您可能还需要添加也在UIView上添加的performWithoutAnimations功能,在这种情况下,您只需将一个null对象添加到堆栈中即可。

在这两种情况中的任何一种情况下,您都可以获取AnimationManager.isAnimatingAnimationManager.animationDurationAnimationManager.animationCurve ...因此,这可以很好地用于您自己对动画的调用。 但是要使这种通用性(例如在设备方向更改上)似乎是一个大问题。 我很确定这些数据一定在某个地方,并且很乐意访问它们。

希望该系统对您有所帮助,除非您找到更合适的解决方案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM