Implementation effect

Looping animation between the main screen and the menu, as you can see above.

Every time I see such an elegant animation, I think like everyone else, how should I achieve it… Wait, isn’t that what normal people think?

In this tutorial, you will learn how to implement this cool animation using Swift. In the process, you will learn if you use the shape the layers, masking, UIViewControllerAnimatedTransitioning protocol and UIPercentDrivenInteractiveTransition class and so on.

Note that this tutorial assumes you have an iOS development background.

The overall strategy

This animation happens when you jump from one view to another.

In iOS, you implement custom animations between other view controllers using the navigation controller UINavigationController. You can also use iOS7 UIViewControllerAnimatedTransitioning protocol transition animations. a.

You have to know the details, and this agreement will help you do that

  • Specifies the animation duration
  • Create a view container associated with two view controllers
  • Implement any animation you can imagine

You can use this to do high-level complex UIView animations or simple low-level Core animations (in this case, you’ll implement the latter)

Implementation strategy

Now that you know where the coded action takes place, the next point is how do you actually implement the looping transition animation

If you wanted to describe the animation in your own words, it would look something like this:

  • There’s a circle in the top right of the view, like a button that opens another view
  • In other words, the circle is like a veil, which opens everything inside and hides everything outside

You can do this with CALayer’s Mask property. You can also use its alpha channel to determine which part of the layer can be displayed




icon

Now that you know what a mask is, the next step is to decide which mask to use. Since the animation is a mask for a prototype. CAShpeLayer is the natural choice. To achieve this circular animation, simply increase the radius of the prototype mask

Custom animation

Note: Omit the previous build project and focus directly on animation creation. Specific project DownloadCopy the code

In order to write a custom push or pop animation, you need to implement UINavigationControllerDelegate animationControllerForOperation method of the agreement.

In the iOS \ Source \ Cocoa Touch Class to create a new file, set up the Class called NavigationControllerDelegate.

After creating the file, implement the class as follows

class NavigationControllerDelegate: NSObject, UINavigationControllerDelegate {

}Copy the code

And then set the UINavigationController agent, back to NavigationControllerDelegate this class, add the method

func navigationController(navigationController: UINavigationController, animationControllerForOperation operation: UINavigationControllerOperation, fromViewController fromVC: UIViewController, toViewController toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
  return nil
}Copy the code

Note that the implementation of this method is empty, and you will implement it in a moment

This method takes two jump in the navigation controller view controller, your task is to return to a UIViewControllerAnimatedTransitioning class

So you need to create one, and then create a class called CircleTransitionAnimator (File\New\File)




icon

Make sure you achieve the UIViewControllerAnimatedTransitioning agreement

class CircleTransitionAnimator: NSObject, UIViewControllerAnimatedTransitioning {Copy the code

The next step is to implement the methods that the protocol needs to implement

So let’s add the following method

Func transitionDuration (transitionContext: UIViewControllerContextTransitioning) - > NSTimeInterval 0.5} {returnCopy the code

In this method, you return the time of the animation. You want the animation to last 0.5 seconds. You return 0.5

Next, add an attribute to the class

weak var transitionContext: UIViewControllerContextTransitioning?Copy the code

You’re going to use it in the transition context

Let’s implement the second method

func animateTransition(transitionContext: UIViewControllerContextTransitioning) { //1 self.transitionContext = transitionContext //2 let containerView = transitionContext.containerView() let fromViewController = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey) as! ViewController let toViewController = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey) as!  ViewController let button = fromViewController.button //3 containerView! .addSubview(toViewController.view) //4 let circleMaskPathInitial = UIBezierPath(ovalInRect: button.frame) let extremePoint = CGPoint(x: button.center.x - 0, y: button.center.y - CGRectGetHeight(toViewController.view.bounds)) let radius = sqrt((extremePoint.x*extremePoint.x) + (extremePoint.y*extremePoint.y)) let circleMaskPathFinal = UIBezierPath(ovalInRect: CGRectInset(button.frame, -radius, -radius)) //5 let maskLayer = CAShapeLayer() maskLayer.path = circleMaskPathFinal.CGPath toViewController.view.layer.mask = maskLayer //6 let maskLayerAnimation = CABasicAnimation(keyPath: "path") maskLayerAnimation.fromValue = circleMaskPathInitial.CGPath maskLayerAnimation.toValue = circleMaskPathFinal.CGPath maskLayerAnimation.duration = self.transitionDuration(transitionContext) maskLayerAnimation.delegate = self maskLayer.addAnimation(maskLayerAnimation, forKey: "path") }Copy the code

Let’s walk through the code step by step

1. We first reference the transitionContext object to ensure that we can reference it outside the function scope 2. Get the view container, start the view controller and end the view controller. There is also the button that causes the event to happen. The view tends to be the view where the animation happens. The start and end view controllers are participants in the animation. 3. Add the end view to the view container 4. Create two circular Bezier curves. One is the same size as button, and the other one has a big enough radius to cover the entire radius. The final animation will be the animation between these two. 5. Create a CAShapeLayer to display the circular mask. Assign it to the finished circle. Avoid bouncing back at the end of the animation. 6. Create a CABasicAnimation based on bezier curves. Animation views that act on the start and end animation views. At the same time, the animation agent is set up to handle the finishing touches of the animation.

Let’s finish the animation

override func animationDidStop(anim: CAAnimation, finished flag: Bool) { self.transitionContext? .completeTransition(! self.transitionContext! .transitionWasCancelled()) self.transitionContext? .viewControllerForKey(UITransitionContextFromViewControllerKey)? .view.layer.mask = nil }Copy the code

The next step is to use the animation effects in NavigationControllerDelegate. Swift

func navigationController(navigationController: UINavigationController,
 animationControllerForOperation operation: UINavigationControllerOperation,
 fromViewController fromVC: UIViewController,
 toViewController toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
    return CircleTransitionAnimator()
}Copy the code

This cool animation is achieved, hurry to try it!

Swipe here to get the code