Custom segue transition animation

回眸只為那壹抹淺笑 提交于 2019-11-28 14:13:04

The best way to achieve that is to create custom push and pop animation by conforming UIViewControllerAnimatedTransitioning protocol:-

//CustomPushAnimation class

import UIKit

class CustomPushAnimation: NSObject, UIViewControllerAnimatedTransitioning {

    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
        return 0.2
    }

    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
        let containerVw = transitionContext.containerView
        let fromViewController = transitionContext.viewController(forKey: .from)
        let toViewController = transitionContext.viewController(forKey: .to)
        guard let fromVc = fromViewController, let toVc = toViewController else { return }
        let finalFrame = transitionContext.finalFrame(for: toVc)
        //Below line will start from left
        toVc.view.frame = finalFrame.offsetBy(dx: -finalFrame.size.width/2, dy: 0)
        containerVw.addSubview(toVc.view)
        UIView.animate(withDuration: transitionDuration(using: transitionContext), animations: {
            toVc.view.frame = finalFrame
            fromVc.view.alpha = 0.5
        }, completion: {(finished) in
            transitionContext.completeTransition(finished)
            fromVc.view.alpha = 1.0
        })
    }
}



//CustomPopAnimation class
import UIKit

class CustomPopAnimation: NSObject, UIViewControllerAnimatedTransitioning {
    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
        return 0.2
    }

    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
        let containerView = transitionContext.containerView
        let fromViewController = transitionContext.viewController(forKey: .from)
        let toViewController = transitionContext.viewController(forKey: .to)
        guard let fromVc = fromViewController,
            let toVc = toViewController,
            let snapshotView = fromVc.view.snapshotView(afterScreenUpdates: false)
            else { return }
        let finalFrame = transitionContext.finalFrame(for: fromVc)
        toVc.view.frame = finalFrame
        containerView.addSubview(toVc.view)
        containerView.sendSubview(toBack: toVc.view)
        snapshotView.frame = fromVc.view.frame
        containerView.addSubview(snapshotView)
        fromVc.view.removeFromSuperview()
        UIView.animate(withDuration: transitionDuration(using: transitionContext), animations: {
            //Below line will start from right
            snapshotView.frame = finalFrame.offsetBy(dx: -finalFrame.size.width, dy: 0)
        }, completion: {(finished) in
            snapshotView.removeFromSuperview()
            transitionContext.completeTransition(finished)
        })
    }
}

And last you need to present the new View controller with setting animation flag to true otherwise it will not work

//Below code should be inside YourViewController
    let vc = UIStoryboard(name: "storyboardName", bundle: nil).instantiateViewController(withIdentifier: "ViewControllerIdentifier")            let navigationController = BaseNavigationController(rootViewController: vc)
    navigationController.transitioningDelegate = self
    present(navigationController, animated: true, completion: nil)

You also need to conform UIViewControllerTransitioningDelegate protocol in order to work animation

  extension YourViewController: UIViewControllerTransitioningDelegate {
    func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
            return customPushAnimation
        }

    func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
            return customPopAnimation
        }
    }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!