Instantly share code, notes, and snippets.
Forked from hikui/MHGSwipeNavigationController.h
Created
March 18, 2014 06:00
-
Star
0
(0)
You must be signed in to star a gist -
Fork
1
(1)
You must be signed in to fork a gist
-
Save baxiang/9614311 to your computer and use it in GitHub Desktop.
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
// | |
// MHGSwipeNavigationController.h | |
// SwipeNavigationController | |
// | |
// Created by 缪和光 on 28/12/2013. | |
// Copyright (c) 2013 Hokuang. All rights reserved. | |
// | |
#import <UIKit/UIKit.h> | |
@interface MHGSwipeNavigationController : UINavigationController | |
@property (nonatomic, strong, readonly) UIPanGestureRecognizer *mhg_popGestureRecognizer; | |
@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
// | |
// MHGSwipeNavigationController.m | |
// SwipeNavigationController | |
// | |
// Created by 缪和光 on 28/12/2013. | |
// Copyright (c) 2013 Hokuang. All rights reserved. | |
// | |
#import "MHGSwipeNavigationController.h" | |
#define KEY_WINDOW [[UIApplication sharedApplication] keyWindow] | |
#define TOP_VIEW (KEY_WINDOW.rootViewController.view) | |
@interface MHGSwipeNavigationController () | |
@property (nonatomic, strong) NSMutableArray *snapshotStack; | |
@property (nonatomic, strong) UIImageView *snapshotImageView; | |
@property (nonatomic, assign) CGFloat lastTouchX; | |
@end | |
@implementation MHGSwipeNavigationController | |
- (id)initWithCoder:(NSCoder *)aDecoder { | |
self = [super initWithCoder:aDecoder]; | |
if (self) { | |
[self commonInit]; | |
} | |
return self; | |
} | |
- (id)initWithRootViewController:(UIViewController *)rootViewController { | |
self = [super initWithRootViewController:rootViewController]; | |
if (self) { | |
[self commonInit]; | |
} | |
return self; | |
} | |
- (id)init { | |
self = [super init]; | |
if (self) { | |
[self commonInit]; | |
} | |
return self; | |
} | |
- (void)commonInit { | |
if ([self respondsToSelector:@selector(interactivePopGestureRecognizer)]) { | |
self.interactivePopGestureRecognizer.enabled = NO; | |
} | |
} | |
- (void)viewDidLoad | |
{ | |
[super viewDidLoad]; | |
UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePanGesture:)]; | |
[self.view addGestureRecognizer:panGestureRecognizer]; | |
_mhg_popGestureRecognizer = panGestureRecognizer; | |
} | |
- (void)viewWillAppear:(BOOL)animated | |
{ | |
[self addShadowForView]; | |
} | |
#pragma mark - capture last view's snapshot | |
- (UIImage *)takeSnapshot | |
{ | |
UIGraphicsBeginImageContextWithOptions(TOP_VIEW.bounds.size, TOP_VIEW.opaque, 0.0); | |
[TOP_VIEW.layer renderInContext:UIGraphicsGetCurrentContext()]; | |
UIImage *snapshot = UIGraphicsGetImageFromCurrentImageContext(); | |
UIGraphicsEndImageContext(); | |
return snapshot; | |
} | |
#pragma mark - override push | |
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated | |
{ | |
if (!self.snapshotStack) { | |
self.snapshotStack = [[NSMutableArray alloc] initWithCapacity:5]; | |
} | |
UIImage *snapshot = [self takeSnapshot]; | |
if (snapshot) [self.snapshotStack addObject:snapshot]; | |
[super pushViewController:viewController animated:animated]; | |
} | |
- (UIViewController *)popViewControllerAnimated:(BOOL)animated | |
{ | |
[self.snapshotStack removeLastObject]; | |
return [super popViewControllerAnimated:animated]; | |
} | |
#pragma mark - handlePanGesture | |
- (void)handlePanGesture:(UIPanGestureRecognizer *)panGestureRecognizer | |
{ | |
if (self.viewControllers.count <= 1) return ; | |
CGPoint point = [panGestureRecognizer locationInView:KEY_WINDOW]; | |
if (panGestureRecognizer.state == UIGestureRecognizerStateBegan) { | |
[self initSnapshot]; | |
self.snapshotImageView.image = [self.snapshotStack lastObject]; | |
self.snapshotImageView.hidden = NO; | |
[TOP_VIEW.superview insertSubview:self.snapshotImageView belowSubview:TOP_VIEW]; | |
self.lastTouchX = point.x; | |
// [self addShadowForView]; | |
} else if (panGestureRecognizer.state == UIGestureRecognizerStateChanged) { | |
CGRect frame = TOP_VIEW.frame; | |
CGFloat newX = (point.x - self.lastTouchX) + frame.origin.x; | |
if (newX < 0) { | |
return; | |
} | |
frame.origin.x = newX; | |
TOP_VIEW.frame = frame; | |
self.lastTouchX = point.x; | |
[self offsetImageViewForX:newX]; | |
} else { | |
[self judgeToPushOrPop]; | |
} | |
} | |
- (void)initSnapshot | |
{ | |
if (!self.snapshotImageView) { | |
self.snapshotImageView = [[UIImageView alloc] initWithFrame:TOP_VIEW.bounds]; | |
} | |
CGRect imageViewFrame = TOP_VIEW.bounds; | |
imageViewFrame.origin.x = -TOP_VIEW.bounds.size.width / 3 * 2; | |
self.snapshotImageView.frame = imageViewFrame; | |
} | |
#pragma mark - judgeToPushOrPop | |
- (void)judgeToPushOrPop | |
{ | |
__block CGRect frame = TOP_VIEW.frame; | |
if (frame.origin.x > (frame.size.width / 3)) { | |
[UIView animateWithDuration:0.3 animations:^{ | |
frame.origin.x = frame.size.width; | |
TOP_VIEW.frame = frame; | |
[self offsetImageViewForX:frame.origin.x]; | |
} completion:^(BOOL finished) { | |
[self popViewControllerAnimated:NO]; | |
self.snapshotImageView.hidden = YES; | |
frame.origin.x = 0; | |
TOP_VIEW.frame = frame; | |
}]; | |
} else { | |
[UIView animateWithDuration:0.3 animations:^{ | |
frame.origin.x = 0; | |
TOP_VIEW.frame = frame; | |
[self offsetImageViewForX:frame.origin.x]; | |
} completion:^(BOOL finished) { | |
self.snapshotImageView.hidden = YES; | |
}]; | |
} | |
} | |
- (void)offsetImageViewForX:(CGFloat)x { | |
CGFloat imageViewX = x / 3 * 2 -TOP_VIEW.bounds.size.width / 3 * 2; | |
CGRect imageViewFrame = self.snapshotImageView.frame; | |
imageViewFrame.origin.x = imageViewX; | |
self.snapshotImageView.frame = imageViewFrame; | |
} | |
- (void)addShadowForView { | |
UIView *shadowedView = self.view; | |
UIBezierPath* newShadowPath = [UIBezierPath bezierPathWithRect:shadowedView.bounds]; | |
shadowedView.layer.masksToBounds = NO; | |
shadowedView.layer.shadowRadius = 10; | |
shadowedView.layer.shadowOpacity = 1; | |
shadowedView.layer.shadowColor = [[UIColor blackColor] CGColor]; | |
shadowedView.layer.shadowOffset = CGSizeZero; | |
shadowedView.layer.shadowPath = [newShadowPath CGPath]; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment