Skip to content

Instantly share code, notes, and snippets.

@litoarias
Created November 30, 2016 17:27
Show Gist options
  • Save litoarias/0fd741b0790dd260270c190ef5f97684 to your computer and use it in GitHub Desktop.
Save litoarias/0fd741b0790dd260270c190ef5f97684 to your computer and use it in GitHub Desktop.
Transition Animator two parts of de middle
@import Foundation;
@interface TTPopAnimator : NSObject <UIViewControllerAnimatedTransitioning>
@end
#import "TTPopAnimator.h"
#define kTransitionDuration .35
@implementation TTPopAnimator
#pragma mark - UIViewControllerAnimatedTransitioning
- (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext
{
return kTransitionDuration;
}
- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext
{
UIViewController* toController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIViewController* fromController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIView* container = [transitionContext containerView];
//get rects that represent the top and bottom halves of the screen
CGSize viewSize = fromController.view.bounds.size;
CGRect topFrame = CGRectMake(0, 0, viewSize.width, viewSize.height/2);
CGRect bottomFrame = CGRectMake(0, viewSize.height/2, viewSize.width, viewSize.height/2);
//create snapshots
UIView* snapshot = [toController.view snapshotViewAfterScreenUpdates:YES];
UIView* snapshotTop = [snapshot resizableSnapshotViewFromRect:topFrame afterScreenUpdates:NO withCapInsets:UIEdgeInsetsZero];
UIView* snapshotBottom = [snapshot resizableSnapshotViewFromRect:bottomFrame afterScreenUpdates:NO withCapInsets:UIEdgeInsetsZero];
//start the frames with an offset
CGRect offsetTopFrame = topFrame;
CGRect offsetBottomFrame = bottomFrame;
offsetTopFrame.origin.y -= topFrame.size.height;
offsetBottomFrame.origin.y += bottomFrame.size.height;
snapshotTop.frame = offsetTopFrame;
snapshotBottom.frame = offsetBottomFrame;
//add our snapshots on top
[container addSubview:snapshotTop];
[container addSubview:snapshotBottom];
[UIView animateKeyframesWithDuration:kTransitionDuration delay:0 options:UIViewKeyframeAnimationOptionCalculationModeLinear animations:^{
//animate the top first
[UIView addKeyframeWithRelativeStartTime:0 relativeDuration:1 animations:^{
snapshotTop.frame = topFrame;
}];
//animate the bottom second
[UIView addKeyframeWithRelativeStartTime:0 relativeDuration:1 animations:^{
snapshotBottom.frame = bottomFrame;
}];
} completion:^(BOOL finished) {
//don't forget to clean up
[snapshotTop removeFromSuperview];
[snapshotBottom removeFromSuperview];
[fromController.view removeFromSuperview];
[container addSubview:toController.view];
[transitionContext completeTransition:finished];
}];
}
@end
@import Foundation;
@interface TTPushAnimator : NSObject <UIViewControllerAnimatedTransitioning>
@end
#import "TTPushAnimator.h"
#define kTransitionDuration .35
@implementation TTPushAnimator
#pragma mark - UIViewControllerAnimatedTransitioning
- (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext
{
return kTransitionDuration;
}
- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext
{
UIViewController* toController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIViewController* fromController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIView* container = [transitionContext containerView];
//get rects that represent the top and bottom halves of the screen
CGSize viewSize = fromController.view.bounds.size;
CGRect topFrame = CGRectMake(0, 0, viewSize.width, viewSize.height/2);
CGRect bottomFrame = CGRectMake(0, viewSize.height/2, viewSize.width, viewSize.height/2);
//create snapshots
UIView* snapshotTop = [fromController.view resizableSnapshotViewFromRect:topFrame afterScreenUpdates:NO withCapInsets:UIEdgeInsetsZero];
UIView* snapshotBottom = [fromController.view resizableSnapshotViewFromRect:bottomFrame afterScreenUpdates:NO withCapInsets:UIEdgeInsetsZero];
snapshotTop.frame = topFrame;
snapshotBottom.frame = bottomFrame;
//remove the original view from the container
[fromController.view removeFromSuperview];
//add our destination view
[container addSubview:toController.view];
//add our snapshots on top
[container addSubview:snapshotTop];
[container addSubview:snapshotBottom];
[UIView animateKeyframesWithDuration:kTransitionDuration delay:0 options:UIViewKeyframeAnimationOptionCalculationModeLinear animations:^{
//adjust the new frames
CGRect newTopFrame = topFrame;
CGRect newBottomFrame = bottomFrame;
newTopFrame.origin.y -= topFrame.size.height;
newBottomFrame.origin.y += bottomFrame.size.height;
//animate the top first
[UIView addKeyframeWithRelativeStartTime:0 relativeDuration:1 animations:^{
snapshotTop.frame = newTopFrame;
}];
//animate the bottom second
[UIView addKeyframeWithRelativeStartTime:0 relativeDuration:1 animations:^{
snapshotBottom.frame = newBottomFrame;
}];
} completion:^(BOOL finished) {
//don't forget to clean up
[snapshotTop removeFromSuperview];
[snapshotBottom removeFromSuperview];
[transitionContext completeTransition:finished];
}];
}
@end
@interface : UIViewController <UINavigationControllerDelegate>
#pragma mark - UINavigationControllerDelegate
- (id <UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController
animationControllerForOperation:(UINavigationControllerOperation)operation
fromViewController:(UIViewController *)fromVC
toViewController:(UIViewController *)toVC
{
switch(operation)
{
case UINavigationControllerOperationPush:
return [[TTPushAnimator alloc] init];
case UINavigationControllerOperationPop:
return [[TTPopAnimator alloc] init];
default:
return nil;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment