Created
June 22, 2014 03:19
-
-
Save andkon/72c7769e853bbb379e4d to your computer and use it in GitHub Desktop.
Interactive Transitions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@interface InteractiveTransition.h : NSObject <UIViewControllerAnimatedTransitioning> | |
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext | |
{ | |
UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey]; | |
CGRect initialFrame = fromVC.view.frame; | |
CGRect finalFrame = CGRectMake( | |
initialFrame.origin.x, | |
initialFrame.size.height + 16, | |
initialFrame.size.width, | |
initialFrame.size.height | |
); | |
// use this option to make it stick under the user's finger: | |
UIViewAnimationOptions *opts = UIViewAnimationOptionCurveLinear; | |
[UIView animateWithDuration:1.0 | |
delay:0.0 | |
options:opts | |
animations:^{ | |
fromVC.view.frame = finalFrame; | |
} | |
completion:^(BOOL finished) { | |
[transitionContext completeTransition:![transitionContext transitionWasCancelled]]; | |
} | |
]; | |
} | |
- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext | |
{ | |
// useless but necessary | |
return 1.0f; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@interface RootVC : UIViewController <UIViewControllerTransitioningDelegate> | |
@property (strong, nonatomic) UIPercentDrivenInteractiveTransition *myInteractiveDismissal; | |
@proprety (strong, nonatomic) BOOL interactive; | |
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import "InteractiveTransition.h" | |
#import "NonInteractiveTransition.h" | |
-(void)openButtonPressed | |
{ | |
ModalVC *modalVC = [[ModalVC alloc] init]; | |
modalVC.modalPresentationStyle = UIModalPresentationCustom; | |
modalVC.transitioningDelegate = self; | |
[self presentViewController:modalVC | |
animated:YES | |
completion:^{ | |
UIPanGestureRecognizer *gesture; | |
gesture = [[UIPanGestureRecognizer alloc] init]; | |
// This method gets called in RootVC: | |
[gesture addTarget:self action:@selector(handleGesture:)]; | |
// The gesture object gets added to modalVC.view: | |
[loginVC.view addGestureRecognizer:gesture]; | |
} | |
]; | |
} | |
- (void)handleGesture:(UIPanGestureRecognizer *)gesture | |
{ | |
switch (gesture.state) { | |
case UIGestureRecognizerStateBegan:{ | |
self.interactive = YES; | |
[self dismissViewControllerAnimated:YES completion:^{ | |
self.interactive = NO; | |
}]; | |
break; | |
} | |
case UIGestureRecognizerStateChanged:{ | |
// Gives us the transition context's container view | |
UIView *view = gesture.view.superview; | |
// This gets us the point of where the gesture is in view: | |
CGPoint translation = [gesture translationInView:view]; | |
CGFloat percentTransitioned = (translation.y / (CGRectGetHeight(view.frame))); | |
[self.myInteractiveDismissal updateInteractiveTransition:percentTransitioned]; | |
break; | |
} | |
case UIGestureRecognizerStateEnded:{ | |
if (self.myInteractiveDismissal.percentComplete > 0.25) { | |
[self.myInteractiveDismissal finishInteractiveTransition]; | |
} else { | |
[self.myInteractiveDismissal cancelInteractiveTransition]; | |
} | |
break; | |
} | |
case UIGestureRecognizerStateCancelled:{ | |
[self.myInteractiveDismissal cancelInteractiveTransition]; | |
} | |
} | |
} | |
- (id <UIViewControllerInteractiveTransitioning>)interactionControllerForDismissal:(id<UIViewControllerAnimatedTransitioning>)animator | |
{ | |
// In animated transitions, we had to create out own classes (eg BouncyTransition) to make the | |
// transition work. In this case, we just use UIPercentDrivenInteractiveTransition. | |
if (self.interactive) { | |
self.myInteractiveDismissal = [[UIPercentDrivenInteractiveTransition alloc] init]; | |
return self.myInteractiveDismissal; | |
} | |
return nil; | |
} | |
// You also need the usual <UIViewControllerTransitioningDelegate> stuff: | |
- (id <UIViewControllerAnimatedTransitioning>) animationControllerForDismissedController:(UIViewController *)dismissed | |
{ | |
id<UIViewControllerAnimatedTransitioning> transition; | |
if (self.interactive) { | |
transition = [[InteractiveTransition alloc] init]; | |
} else { | |
transition = [[NonInteractiveTransition alloc] init]; | |
} | |
return transition; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment