IOS 7 changes direction of pushviewcontroller animation

When I click on the viewcontroller, the animation is always right to left. I want to reverse this animation from left to right. I tried this code but not working. The animation is still right to left. How can I achieve this simply and correctly? Need help please. Thanks in advance.

//NOT WORKING myViewController *mController = [self.storyboard instantiateViewControllerWithIdentifier:@"myViewController"]; CATransition *transition = [CATransition animation]; transition.duration = 0.3; transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; transition.type = kCATransitionPush; transition.subtype = kCATransitionFromLeft; [self.view.layer addAnimation:transition forKey:nil]; [self.navigationController pushViewController:mController animated:YES]; 
+6
source share
7 answers

You actually do it right, but as far as I understand from your code, you are not overriding the method:

 - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated 

So, you need to inherit from the UINavigationController and override the above method.

This is how I do it (push + pop):

Click

 - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated{ UIView *theWindow = self.view ; if( animated ) { CATransition *animation = [CATransition animation]; [animation setDuration:0.45f]; [animation setType:kCATransitionPush]; [animation setSubtype:kCATransitionFromLeft]; [animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]]; [[theWindow layer] addAnimation:animation forKey:@""]; } //make sure we pass the super "animated:NO" or we will get both our //animation and the super animation [super pushViewController:viewController animated:NO]; [self swapButtonsForViewController:viewController]; } 

Pop:

 - (UIViewController *)popViewControllerAnimated:(BOOL)animated { UIView *theWindow = self.view ; if( animated ) { CATransition *animation = [CATransition animation]; [animation setDuration:0.45f]; [animation setType:kCATransitionPush]; [animation setSubtype:kCATransitionFromRight]; [animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]]; [[theWindow layer] addAnimation:animation forKey:@""]; } return [super popViewControllerAnimated:NO]; } 
+9
source

Since iOS 7 is mentioned in this question, I am very surprised that the answer does not mention the Animated Transitions API introduced in iOS 7.

If you want to go straight to GitHub, the objc.io guys have a great post with a related project here

Take a look at the documentation and you will see the following:

 @availability(iOS, introduced=7.0) optional func navigationController(navigationController: UINavigationController, animationControllerForOperation operation: UINavigationControllerOperation, fromViewController fromVC: UIViewController, toViewController toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? 

Or in Objective-C

 - (id <UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC NS_AVAILABLE_IOS(7_0); 

This means that from iOS 7 you can control how the navigation controller implements its animations for taps and exits.

All you need to do is set the delegate of the navigation controller and, if necessary, provide the correct animator object. So let's get started:

1. Set UINavigationControllerDelegate

I usually like to have an App-Wide navigation coordinator that manages all my transitions, etc. Ideally, you want an object to be alive throughout the entire navigation period of the NavigationController. So we can have a coordinator that looks like this:

 class NavigationCoordinationController: NSObject { private(set) var navigationController:UINavigationController required init(navigationController: UINavigationController) { self.navigationController = navigationController super.init() navigationController.delegate = self } } 

I usually create this in the App Delegate, so it can be referenced anywhere. You can also set a delegate based on each controller by creating a custom subclass of UINavigationController or wherever you are.

2. Create a custom animator

Now we need an object that conforms to the UIViewControllerAnimatedTransitioning protocol. This object will be called upon to apply animation whenever an animated transition is needed. This example is a simple animation that fades and extends the fromView value on transition, so it matters for Push.

 class CustomPushExpansionTransitioner: NSObject, UIViewControllerAnimatedTransitioning { func transitionDuration(transitionContext: UIViewControllerContextTransitioning) -> NSTimeInterval { return 1 } func animateTransition(transitionContext: UIViewControllerContextTransitioning) { let fromView: UIView = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey)! let toView: UIView = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey)! let container = transitionContext.containerView() container.addSubview(toView) container.bringSubviewToFront(fromView) toView.frame = container.convertRect(fromView.bounds, fromView: fromView) UIView.animateWithDuration(transitionDuration(transitionContext), animations: { () -> Void in fromView.alpha = 0 fromView.transform = CGAffineTransformConcat(fromView.transform, CGAffineTransformMakeScale(1.3, 1.3)) }) { (complete) -> Void in transitionContext.completeTransition(true) } } } 

3. Vend Animator Where Necessary

Now we need to implement the UINavigationController delegate and, if necessary, provide our custom animator.

 extension NavigationCoordinationController: UINavigationControllerDelegate { func navigationController(navigationController: UINavigationController, animationControllerForOperation operation: UINavigationControllerOperation, fromViewController fromVC: UIViewController, toViewController toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? { switch operation { case .Push: return LaunchToHomeTransitioner() case .Pop: break case .None: break } return nil } } 

And now, you now have full control over the transitions of the UINavigationController

+11
source
 NextViewController *next = [[NextViewController alloc] initWithNibName:@"NextViewController" bundle:nil]; [UIView transitionWithView:self.navigationController.view duration:0.75 options:UIViewAnimationOptionTransitionFlipFromRight animations:^{ [self.navigationController pushViewController:next animated:NO]; } completion:nil]; 

Try to code

+4
source

You can also try this.

 CATransition *transition = [CATransition animation]; transition.duration = 0.5; transition.type = kCATransitionMoveIn; transition.subtype = kCATransitionFromLeft; transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; [self.navigationController.view.layer addAnimation:transition forKey:kCATransition]; DrawingResultsViewController *dr = [DrawingResultsViewController createAndShowProfile:YES]; [self.navigationController pushViewController:dr animated:YES]; 
+2
source

If someone is looking for the same answer in Xamarin.iOS (based on gran33 ):

 public override void PushViewController(UIViewController viewController, bool animated) { if (animated) { CATransition animation = new CATransition() { Duration = 0.5, Type = CAAnimation.TransitionPush, Subtype = CAAnimation.TransitionFromTop, TimingFunction = AMediaTimingFunction.FromName(CAMediaTimingFunction.EaseInEaseOut) }; View.Layer.AddAnimation(animation, CALayer.Transition); base.PushViewController(viewController, false); } } public override UIViewController PopViewController(bool animated) { if (animated) { CATransition animation = new CATransition() { Duration = 0.5, Type = CAAnimation.TransitionPush, Subtype = CAAnimation.TransitionFromBottom, TimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.EaseInEaseOut) }; View.Layer.AddAnimation(animation, CALayer.Transition); return base.PopViewController(false); } return base.PopViewController(animated); } 
0
source

Assuming myViewController is your view controller, pass the custom transition to the nav controller layer.

 CATransition *transition = [CATransition animation]; transition.type = kCATransitionPush; transition.subtype = kCATransitionFromLeft; [self.navigationController.view.layer addAnimation:transition forKey:@"pushViewController"]; [self.navigationController pushViewController:myViewController animated:NO]; 
0
source

For Swift 4.0+

1 - Create extension:

 extension UINavigationController { func customPopView(_ viewController: UIViewController) { let transition: CATransition = CATransition() transition.duration = 0.3 transition.type = CATransitionType.push transition.subtype = CATransitionSubtype.fromLeft view.layer.add(transition, forKey: nil) pushViewController(viewController, animated: false) } } 

2 - Call:

 self.navigationController?.customPopView(yourViewController) 
0
source

Source: https://habr.com/ru/post/1205089/


All Articles