How to present view controller from right to left in iOS using Swift How to present view controller from right to left in iOS using Swift ios ios

How to present view controller from right to left in iOS using Swift


It doesn't matter if it is xib or storyboard that you are using. Normally, the right to left transition is used when you push a view controller into presentor's UINavigiationController.

UPDATE

Added timing function kCAMediaTimingFunctionEaseInEaseOut

Sample project with Swift 4 implementation added to GitHub


Swift 3 & 4.2

let transition = CATransition()transition.duration = 0.5transition.type = CATransitionType.pushtransition.subtype = CATransitionSubtype.fromRighttransition.timingFunction = CAMediaTimingFunction(name:CAMediaTimingFunctionName.easeInEaseOut)view.window!.layer.add(transition, forKey: kCATransition)present(dashboardWorkout, animated: false, completion: nil)


ObjC

CATransition *transition = [[CATransition alloc] init];transition.duration = 0.5;transition.type = kCATransitionPush;transition.subtype = kCATransitionFromRight;[transition setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];[self.view.window.layer addAnimation:transition forKey:kCATransition];[self presentViewController:dashboardWorkout animated:false completion:nil];


Swift 2.x

let transition = CATransition()transition.duration = 0.5transition.type = kCATransitionPushtransition.subtype = kCATransitionFromRighttransition.timingFunction = CAMediaTimingFunction(name:kCAMediaTimingFunctionEaseInEaseOut)view.window!.layer.addAnimation(transition, forKey: kCATransition)presentViewController(dashboardWorkout, animated: false, completion: nil)

Seems like the animated parameter in the presentViewController method doesn't really matter in this case of custom transition. It can be of any value, either true or false.


Complete code for present/dismiss, Swift 3

extension UIViewController {    func presentDetail(_ viewControllerToPresent: UIViewController) {        let transition = CATransition()        transition.duration = 0.25        transition.type = kCATransitionPush        transition.subtype = kCATransitionFromRight        self.view.window!.layer.add(transition, forKey: kCATransition)        present(viewControllerToPresent, animated: false)    }    func dismissDetail() {        let transition = CATransition()        transition.duration = 0.25        transition.type = kCATransitionPush        transition.subtype = kCATransitionFromLeft        self.view.window!.layer.add(transition, forKey: kCATransition)        dismiss(animated: false)    }}


Read up all answers and can't see correct solution. The right way do to so is to make custom UIViewControllerAnimatedTransitioning for presented VC delegate.

So it assumes to make more steps, but the result is more customizable and haven't some side effects, like moving from view together with presented view.

So, assume you have some ViewController, and there is a method for presenting

var presentTransition: UIViewControllerAnimatedTransitioning?var dismissTransition: UIViewControllerAnimatedTransitioning?    func showSettings(animated: Bool) {    let vc = ... create new vc to present    presentTransition = RightToLeftTransition()    dismissTransition = LeftToRightTransition()    vc.modalPresentationStyle = .custom    vc.transitioningDelegate = self    present(vc, animated: true, completion: { [weak self] in        self?.presentTransition = nil    })}

presentTransition and dismissTransition is used for animating your view controllers. So you adopt your ViewController to UIViewControllerTransitioningDelegate:

extension ViewController: UIViewControllerTransitioningDelegate {    func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {        return presentTransition    }    func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {        return dismissTransition    }}

So the last step is to create your custom transition:

class RightToLeftTransition: NSObject, UIViewControllerAnimatedTransitioning {    let duration: TimeInterval = 0.25    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {        return duration    }    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {        let container = transitionContext.containerView        let toView = transitionContext.view(forKey: .to)!        container.addSubview(toView)        toView.frame.origin = CGPoint(x: toView.frame.width, y: 0)        UIView.animate(withDuration: duration, delay: 0, options: .curveEaseOut, animations: {            toView.frame.origin = CGPoint(x: 0, y: 0)        }, completion: { _ in            transitionContext.completeTransition(true)        })    }}class LeftToRightTransition: NSObject, UIViewControllerAnimatedTransitioning {    let duration: TimeInterval = 0.25    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {        return duration    }    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {        let container = transitionContext.containerView        let fromView = transitionContext.view(forKey: .from)!        container.addSubview(fromView)        fromView.frame.origin = .zero        UIView.animate(withDuration: duration, delay: 0, options: .curveEaseIn, animations: {            fromView.frame.origin = CGPoint(x: fromView.frame.width, y: 0)        }, completion: { _ in            fromView.removeFromSuperview()            transitionContext.completeTransition(true)        })    }}

In that code view controller is presented over current context, you can make your customizations from that point. Also you may see custom UIPresentationController is useful as well (pass in using UIViewControllerTransitioningDelegate)