It’s not just animation that makes an App high-end, but it’s definitely animation that makes an App feel high-end. The company’s project is the voice piece, saw a few competing products, feel our transition is really as hard as steel! Briefly studied the transition animation (Push and Present), applied to the project, can make the App feel a little more high-end.

** Set the navigationController to set an agent, and then implement the following method:

func navigationController(_ navigationController: UINavigationController, animationControllerFor operation: UINavigationController.Operation, from fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {let the transition = TransitionPushAniManager. Init (duration: 0.5, pushType: (operation = =. Push)? .push : .pop) return transition }Copy the code

TransitionPushAniManager is a followed UIViewControllerAnimatedTransitioning agreement the instance of the class. The following two methods are implemented in TransitionPushAniManager:

/ / / return the animation time func transitionDuration (using transitionContext: UIViewControllerContextTransitioning?) Func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { if pushType == .push { pushAnimateTransition(using: transitionContext) } else { popAnimateTransition(using: transitionContext) } }Copy the code

Then in the pushAnimateTransition(using: transitionContext) and popAnimateTransition(using: transitionContext) do animation implementation!

** To create a modal transition, you need to set the transitioningDelegate of the page controller you want to go to, and then implement the following method:

/// present func animationController(forPresented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {return TransitionModalAniManager. Init (duration: 0.5, modalType: .present)} /// return the method - dismiss func animationController(forDismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {return TransitionModalAniManager. Init (duration: 0.5, modalType: dismiss)}Copy the code

TransitionModalAniManager is a followed UIViewControllerAnimatedTransitioning agreement the instance of the class. In TransitionModalAniManager implementation agreement and push the same two methods as follows:

/ / / return the animation time func transitionDuration (using transitionContext: UIViewControllerContextTransitioning?) Func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { if modelType == .present { presentAnimateTransition(using: transitionContext) } else { dismissAnimateTransition(using: transitionContext) } }Copy the code

Then animate in the presentAnimateTransition(using: transitionContext) and dismissAnimateTransition(using: transitionContext)!

TabbarController animated transitions: * * * * is similar to a Push, Modal, TabbarController transitions are also set UITabBarControllerDelegate agent first, and then implement a callback method is as follows:

Func tabBarController(_ tabBarController: UITabBarController, animationControllerForTransitionFrom fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? { return TransitionTabbarAniManager.init() }Copy the code

TransitionTabbarAniManager is a follow UIViewControllerAnimatedTransitioning class instances, and implements the following methods:

/// Implement the transition method func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { guard let fromVc = transitionContext.viewController(forKey: .from), let fromView = fromVc.view, let toVc = transitionContext.viewController(forKey: .to), let toView = toVc.view else { return } let containerView = transitionContext.containerView containerView.addSubview(toView) let startPoint = CGPoint.init(x: 0, y: 0) let radius: Let startPath = UIBezierPath.init(arcCenter: startPoint, radius: Radius, startAngle: 0.0, endAngle: CGFloat(2 * Double. PI) true) let x = startPoint.x let y = startPoint.y let radius_x = (x > containerView.frame.size.width - x) ? x : (containerView.frame.size.width - x) let radius_y = (y > containerView.frame.size.height - y) ? y : (containerView.frame.size.height - y) let endRadius = sqrt(pow(radius_x, 2) + pow(radius_y, 2)) let endPath = UIBezierPath.init(arcCenter: startPoint, radius: endRadius, startAngle: 0, endAngle: CGFloat(2 * Double.pi), clockwise: true) let shapeLayer = CAShapeLayer.init() shapeLayer.path = endPath.cgPath toView.layer.mask = shapeLayer let animation  = CABasicAnimation.init(keyPath: "path") animation.fromValue = startPath.cgPath animation.duration = duration shapeLayer.add(animation, forKey: nil) DispatchQueue.main.asyncAfter(deadline: .now() + duration) { shapeLayer.removeAllAnimations() fromView.removeFromSuperview() transitionContext.completeTransition(! transitionContext.transitionWasCancelled) } }Copy the code

The rough code can be swept: transition animation