The first protocol you will define is called ViewEffectAnimatorType. This protocol should be applied to any object that implements the required behaviors to animate a view. This protocol does not necessarily give you a direct advantage, but there are a few considerations that make this a very useful protocol.
A protocol is not only used to check whether an object can do something. It can also formalize a certain API that you came up with. In this case, BounceAnimationHelper needed certain initializers. It also needs to hold on to an animator, and it has a startAnimation method. These traits are not specific to the bounce animation and might be relevant for several other animation effects.
Adding a protocol to this helper makes sure that any other helpers that conform to the same protocol have the same interface. This helps you, the developer, make sense of what you should minimally implement for your new animation helper. It also makes adding new effects or swapping one effect for another effect very easy and straightforward.
Another advantage is that the startAnimation method can be moved to a protocol extension. Its implementation is simple and straightforward, and you typically won't need to customize it, so it's a great candidate to provide a default implementation for. Create a new Swift file named ViewEffectAnimatorType, and add it to a new folder called Protocols. Now add the following implementation for the protocol:
import UIKit typealias ViewEffectAnimatorComplete = (UIViewAnimatingPosition) -> Void protocol ViewEffectAnimatorType { var animator: UIViewPropertyAnimator { get } init(targetView: UIView, onComplete: @escaping ViewEffectAnimatorComplete) init(targetView: UIView, onComplete: @escaping ViewEffectAnimatorComplete, duration: TimeInterval) func startAnimation() } extension ViewEffectAnimatorType { func startAnimation() { animator.startAnimation() } }
This protocol defines all of the requirements for an animation helper. Note that a globally-available typealias named ViewEffectAnimatorComplete has been defined. This means that you can replace the type declaration for onBounceComplete in ViewController, so it is called ViewEffectAnimatorComplete instead of BounceAnimationHelper.BounceAnimationComplete. This enables you to use the same completion-handler type across the app, which enhances code consistency. To use this protocol, update the initializers for BounceAnimationHelper to use the new typealias and remove the old one. Also, remove the startAnimation method, and finally, add ViewEffectAnimatorType to the BounceAnimationHelper definition, as shown in the following code:
struct BounceAnimationHelper: ViewEffectAnimatorType
By conforming BounceAnimationHelper to ViewEffectAnimatorType, it uses the protocol extension's default implementation for startAnimation, and you have a predictable, formalized interface for BounceAnimationHelper and any future effects that you may wish to add to the app. Let's add a protocol to our contact object as well.