Skip to content

Instantly share code, notes, and snippets.

@ArtFeel
Last active August 1, 2019 21:23
Show Gist options
  • Save ArtFeel/7690431 to your computer and use it in GitHub Desktop.
Save ArtFeel/7690431 to your computer and use it in GitHub Desktop.
Simple sliding transitioning for navigation controller mimics pre iOS7 push/pop animations.All you need, is simply set delegate for you navigation controller: self.navigationController.delegate = self.navigationTransitioningDelegate;NavigationController does not retain delegate, so you should hold it. Note: this code is free (http://unlicense.org)
//
// MGNavigationTransitioningDelegate
//
// Created by Philip Vasilchenko on 27.11.13.
//
#import <UIKit/UIKit.h>
@interface MGNavigationTransitioningDelegate : NSObject <UINavigationControllerDelegate>
@property (nonatomic, strong) id<UIViewControllerAnimatedTransitioning> pushTransitioning;
@property (nonatomic, strong) id<UIViewControllerAnimatedTransitioning> popTransitioning;
@end
//
// MGNavigationTransitioningDelegate
//
// Created by Philip Vasilchenko on 27.11.13.
//
#import "MGNavigationTransitioningDelegate.h"
#import "MGSlideAnimatedTransitioning.h"
@implementation MGNavigationTransitioningDelegate
- (id)init {
self = [super init];
if ( self ) {
self.pushTransitioning = [MGSlideAnimatedTransitioning transitioningWithReverse:NO];
self.popTransitioning = [MGSlideAnimatedTransitioning transitioningWithReverse:YES];
}
return self;
}
- (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController
animationControllerForOperation:(UINavigationControllerOperation)operation
fromViewController:(UIViewController*)fromViewController
toViewController:(UIViewController*)toViewController {
return operation == UINavigationControllerOperationPush ? self.pushTransitioning : self.popTransitioning;
}
@end
//
// MGSlideAnimatedTransitioning
//
// Created by Philip Vasilchenko on 27.11.13.
//
#import <UIKit/UIKit.h>
@interface MGSlideAnimatedTransitioning : NSObject <UIViewControllerAnimatedTransitioning>
@property (nonatomic, assign) BOOL reverse;
- (instancetype)initWithReverse:(BOOL)reverse;
+ (instancetype)transitioningWithReverse:(BOOL)reverse;
@end
//
// MGSlideAnimatedTransitioning
//
// Created by Philip Vasilchenko on 27.11.13.
//
#import "MGSlideAnimatedTransitioning.h"
@implementation MGSlideAnimatedTransitioning
static const NSTimeInterval kMGSlideAnimatedTransitioningDuration = 0.3f;
#pragma mark - Initialization
- (instancetype)initWithReverse:(BOOL)reverse {
self = [super init];
if ( self ) {
self.reverse = reverse;
}
return self;
}
+ (instancetype)transitioningWithReverse:(BOOL)reverse {
return [[self alloc] initWithReverse:reverse];
}
#pragma mark - Transitioning
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext {
NSString * fromKey = UITransitionContextFromViewControllerKey;
NSString * toKey = UITransitionContextToViewControllerKey;
UIViewController * fromViewController = [transitionContext viewControllerForKey:fromKey];
UIViewController * toViewController = [transitionContext viewControllerForKey:toKey];
UIView * containerView = [transitionContext containerView];
UIView * fromView = fromViewController.view;
UIView * toView = toViewController.view;
NSTimeInterval duration = [self transitionDuration:transitionContext];
CGFloat viewWidth = CGRectGetWidth(containerView.frame);
__block CGRect fromViewFrame = fromView.frame;
__block CGRect toViewFrame = toView.frame;
toViewFrame.origin.x = self.reverse ? -viewWidth : viewWidth;
toView.frame = toViewFrame;
[containerView addSubview:toView];
[UIView animateWithDuration:duration
delay:0
options:UIViewAnimationOptionCurveEaseInOut
animations:^{
toViewFrame.origin.x = CGRectGetMinX(containerView.frame);
fromViewFrame.origin.x = self.reverse ? viewWidth : -viewWidth;
toView.frame = toViewFrame;
fromView.frame = fromViewFrame;
}
completion:^(BOOL finished) {
if ( self.reverse ) { [fromView removeFromSuperview]; }
[transitionContext completeTransition:![transitionContext transitionWasCancelled]];
}];
}
- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext {
return kMGSlideAnimatedTransitioningDuration;
}
@end
@alexiscreuzot
Copy link

Any idea on how to get this to be interactive?

@tapannathvani
Copy link

Can you please tell me how to use these classes in my project ?

@jaramire
Copy link

jaramire commented Nov 2, 2016

Hello,
Although this brought back the transition I needed, if I rotated my app after using the transition and then transitioned back, the frame would be the "old" frame and not the new rotation. I had to make this change to make sure I was transitioning back to the proper view:
//__block CGRect toViewFrame = toView.frame;
__block CGRect toViewFrame = [transitionContext finalFrameForViewController:toViewController];

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment