'How to make UIImageView animation wait for dynamicAnimator behavior to finish to start animating

I'm working on an animation for an app, where a shoe box falls from the top of the screen and lands on a pedestal, then the box opens.

I was wondering if there was any way to make the animation for opening the box to wait for the box to get settled on the pedestal before performing the opening animation?

Here's my code:

//dropping box from off screen and having it stop on the pedestal
    dynamicAnimator = UIDynamicAnimator(referenceView: self.view)
    //gravity
    gravityBehavior = UIGravityBehavior(items: [shoeBoxImage])
    dynamicAnimator.addBehavior(gravityBehavior)
    //collision
    collisionBehavior = UICollisionBehavior(items: [shoeBoxImage])
    collisionBehavior.addBoundary(withIdentifier: "Pedestal" as NSCopying, from: CGPoint(x: view.frame.minX, y: 545), to: CGPoint(x: view.frame.maxX, y: 545))
    dynamicAnimator.addBehavior(collisionBehavior)
    //bouncing effect
    bouncingBehavior = UIDynamicItemBehavior(items: [shoeBoxImage])
    bouncingBehavior.elasticity = 0.40
    dynamicAnimator.addBehavior(bouncingBehavior)
    
    //Load Data Here
    Task {
        Shoes = try await queryShoes()
    }
    
    //Opening the box
    shoeBoxImage.shoeBox.animationImages = boxOpeningAnimation
    shoeBoxImage.shoeBox.animationDuration = 1.0
    shoeBoxImage.shoeBox.animationRepeatCount = 1
    shoeBoxImage.shoeBox.contentMode = .scaleAspectFit
    shoeBoxImage.shoeBox.startAnimating()
    shoeBoxImage.shoeBox.image = UIImage(named: "frame11")

Is there any way to do this besides checking for the image view's center position in order to set a bool, then using the said bool to determine whether or not to start animating? If so, could someone please explain how to do so? It would be very much appreciated.



Solution 1:[1]

There is a delegate method that you can use to know when the dynamic animator pauses.

Assign an object as a delegate to the animator

dynamicAnimator.delegate = self

and then implement the dynamicAnimatorDidPause method.

extension ViewController: UIDynamicAnimatorDelegate {
    public func dynamicAnimatorDidPause(_ animator: UIDynamicAnimator) {
        //Start your box opening animation here...
    }
}

Below is an excerpt from UIDynamicAnimator Apple Developer Documentation.

All types of dynamic animators share the following characteristics:

  • Each dynamic animator is independent of other dynamic animators you create

  • You can associate a given dynamic item with multiple behaviors, provided those behaviors belong to the same animator

  • An animator automatically pauses when all its items are at rest, and automatically resumes when a behavior parameter changes or a behavior or item is added or removed

You can implement a delegate to respond to changes in animator pause/resumption status, using the dynamicAnimatorDidPause(_:) and dynamicAnimatorWillResume(_:) methods of the UIDynamicAnimatorDelegate protocol.


You have to note here that the animator might not call dynamicAnimatorDidPause even though it would seem that the animations have stopped. This could be due to some minuscule changes in parameters of the animated object that is not necessarily visible to the eye. If that happens, you have to consider changing some animation properties so that the animation stops quickly without wiggling around.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1