-
-
Save ArtFeel/7690431 to your computer and use it in GitHub Desktop.
// | |
// 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 |
Great approach!
In case the navigation bar is hidden for one view controller and visible for the other, you need a little adjustment. In the animation block, below line 56, add:
toViewFrame.origin.y = toViewController.navigationController.navigationBarHidden ?
0 : toViewController.navigationController.navigationBar.frame.origin.y +
toViewController.navigationController.navigationBar.frame.size.height;
Works great with swift too - thanks
Navigation bar does not move along with viewcontroller, results in navigationbar updates later. Can anyone please give a fix for this?
Any idea on how to get this to be interactive?
Can you please tell me how to use these classes in my project ?
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];
@StanchoBancho, thanks for the feedback, I fixed it.
In my previous code I'm using FrameAccessor pod, highly recommend it.