Skip to content

Efficiently coordinating multiple animators on a composite object #35

@jverkoey

Description

@jverkoey

I am animating an MKMapCamera and have different animators for each of the sub-properties which I use to animate different properties of the camera with different vibes.

AnimationGroup seems like it would be a natural candidate for this, but the interface assumes you're using the same Animations for the lifetime of the group, and that they all run as a unit. I want to be able to initiate and even hand off animations from one type to another (e.g. a decay that turns into a spring), so the AnimationGroup is a bit too restrictive as-is.

One thing I'm playing with but is somewhat messy in its own way is to introduce events at the start and end of Animator's tick pump, like so:

    // MARK: - AnimationDriverObserver

    public var tickWillStart: (() -> Void)?

    /// Informs an observer that a tick occurred and that one or animations updated.
    public var tickDidEnd: ((Bool) -> Void)?

    func tick(frame: AnimationFrame) {
        tickWillStart?()

        var anyAnimationUpdated = false

        for animation in (runningAnimations.copy() as! NSHashTable<AnyObject>).objectEnumerator() {
            // This is such a hack.
            if let animation = animation as? AnimationDriverObserver {
                animation.tick(frame: frame)
                anyAnimationUpdated = true
            }
        }

        tickDidEnd?(anyAnimationUpdated)
    }

This allows me to set up scratch state at the start of the tick, mutate it with any animators that are running, and then commit the result atomically, rather than having each animator commit the presentation data to the model layer individually.

Curious on any thoughts on this!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions