forked from hartlco/MHCustomTabBarController
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
372 additions
and
70 deletions.
There are no files selected for viewing
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,19 @@ | ||
// | ||
// MHNavigationController.h | ||
// MHCustomTabBarControllerDemo | ||
// MLNavigationController.h | ||
// MultiLayerNavigation | ||
// | ||
// Created by Vienta on 14/11/22. | ||
// Copyright (c) 2014年 Martin Hartl. All rights reserved. | ||
// Created by Feather Chan on 13-4-12. | ||
// Copyright (c) 2013年 Feather Chan. All rights reserved. | ||
// | ||
|
||
#import <UIKit/UIKit.h> | ||
|
||
extern NSString *const MHTabBarControllerViewControllerPushNotification; | ||
extern NSString *const MHTabBarControllerViewControllerPopNotification; | ||
|
||
extern NSString *const MHNavigationControllerViewControllerWillShowNotification; | ||
extern NSString *const MHNavigationControllerViewControllerDidShowNotification; | ||
@interface MHNavigationController : UINavigationController <UIGestureRecognizerDelegate> | ||
|
||
@interface MHNavigationController : UINavigationController<UINavigationControllerDelegate> | ||
// Enable the drag to back interaction, Defalt is YES. | ||
@property (nonatomic,assign) BOOL canDragBack; | ||
|
||
@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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,79 +1,261 @@ | ||
// | ||
// MHNavigationController.m | ||
// MHCustomTabBarControllerDemo | ||
// MLNavigationController.m | ||
// MultiLayerNavigation | ||
// | ||
// Created by Vienta on 14/11/22. | ||
// Copyright (c) 2014年 Martin Hartl. All rights reserved. | ||
// Created by Feather Chan on 13-4-12. | ||
// Copyright (c) 2013年 Feather Chan. All rights reserved. | ||
// | ||
|
||
#define KEY_WINDOW [[UIApplication sharedApplication]keyWindow] | ||
#define TOP_VIEW [[UIApplication sharedApplication]keyWindow].rootViewController.view | ||
|
||
|
||
#import "MHNavigationController.h" | ||
#import <QuartzCore/QuartzCore.h> | ||
|
||
NSString *const MHNavigationControllerViewControllerWillShowNotification = @"kMHNavigationControllerViewControllerWillShowNotification"; | ||
NSString *const MHNavigationControllerViewControllerDidShowNotification = @"kMHNavigationControllerViewControllerDidShowNotification"; | ||
NSString *const MHTabBarControllerViewControllerPushNotification = @"MHTabBarControllerViewControllerPushNotification"; | ||
NSString *const MHTabBarControllerViewControllerPopNotification = @"MHTabBarControllerViewControllerPopNotification"; | ||
|
||
@interface MHNavigationController () | ||
{ | ||
CGPoint startTouch; | ||
|
||
UIImageView *lastScreenShotView; | ||
UIView *blackMask; | ||
} | ||
|
||
@property (nonatomic,retain) UIView *backgroundView; | ||
@property (nonatomic,retain) NSMutableArray *screenShotsList; | ||
|
||
@property (nonatomic,assign) BOOL isMoving; | ||
|
||
@end | ||
|
||
@implementation MHNavigationController | ||
|
||
- (void)viewDidLoad { | ||
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil | ||
{ | ||
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; | ||
if (self) { | ||
// Custom initialization | ||
[self setUp]; | ||
} | ||
return self; | ||
} | ||
|
||
- (void)setUp | ||
{ | ||
self.screenShotsList = [[NSMutableArray alloc]initWithCapacity:2]; | ||
self.canDragBack = YES; | ||
} | ||
|
||
- (void)dealloc | ||
{ | ||
self.screenShotsList = nil; | ||
|
||
[self.backgroundView removeFromSuperview]; | ||
self.backgroundView = nil; | ||
} | ||
|
||
- (void)viewDidLoad | ||
{ | ||
[super viewDidLoad]; | ||
// Do any additional setup after loading the view. | ||
[self setUp]; | ||
// draw a shadow for navigation view to differ the layers obviously. | ||
// using this way to draw shadow will lead to the low performace | ||
// the best alternative way is making a shadow image. | ||
// | ||
//self.view.layer.shadowColor = [[UIColor blackColor]CGColor]; | ||
//self.view.layer.shadowOffset = CGSizeMake(5, 5); | ||
//self.view.layer.shadowRadius = 5; | ||
//self.view.layer.shadowOpacity = 1; | ||
if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1) { | ||
self.interactivePopGestureRecognizer.delegate = nil; | ||
self.interactivePopGestureRecognizer.enabled = NO; | ||
} | ||
self.delegate = (id)self; | ||
UIImageView *shadowImageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"leftside_shadow_bg"]]; | ||
shadowImageView.frame = CGRectMake(-10, 0, 10, TOP_VIEW.frame.size.height); | ||
[TOP_VIEW addSubview:shadowImageView]; | ||
|
||
UIPanGestureRecognizer *recognizer = [[UIPanGestureRecognizer alloc]initWithTarget:self | ||
action:@selector(paningGestureReceive:)]; | ||
recognizer.delegate = self; | ||
[recognizer delaysTouchesBegan]; | ||
[self.view addGestureRecognizer:recognizer]; | ||
} | ||
|
||
- (void)didReceiveMemoryWarning { | ||
- (void)didReceiveMemoryWarning | ||
{ | ||
[super didReceiveMemoryWarning]; | ||
// Dispose of any resources that can be recreated. | ||
} | ||
|
||
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated | ||
- (void)viewDidAppear:(BOOL)animated | ||
{ | ||
NSLog(@"~~~~~~~~~~~~will show:%@", viewController); | ||
[[NSNotificationCenter defaultCenter] postNotificationName:MHNavigationControllerViewControllerWillShowNotification object:viewController]; | ||
[super viewDidAppear:(BOOL)animated]; | ||
|
||
if (self.screenShotsList.count == 0) { | ||
|
||
UIImage *capturedImage = [self capture]; | ||
|
||
if (capturedImage) { | ||
[self.screenShotsList addObject:capturedImage]; | ||
} | ||
} | ||
} | ||
|
||
- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated | ||
// override the push method | ||
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated | ||
{ | ||
NSLog(@"~~~~~~~~~~~~did show:%@", viewController); | ||
[[NSNotificationCenter defaultCenter] postNotificationName:MHNavigationControllerViewControllerDidShowNotification object:viewController]; | ||
UIImage *capturedImage = [self capture]; | ||
|
||
if (capturedImage) { | ||
[self.screenShotsList addObject:capturedImage]; | ||
} | ||
|
||
dispatch_async(dispatch_get_main_queue(), ^{ | ||
[[NSNotificationCenter defaultCenter] postNotificationName:MHTabBarControllerViewControllerPushNotification object:viewController]; | ||
}); | ||
|
||
[super pushViewController:viewController animated:animated]; | ||
} | ||
/* | ||
- (NSUInteger)navigationControllerSupportedInterfaceOrientations:(UINavigationController *)navigationController | ||
|
||
// override the pop method | ||
- (UIViewController *)popViewControllerAnimated:(BOOL)animated | ||
{ | ||
NSLog(@"~~~~~~~~~~~~%s", __PRETTY_FUNCTION__); | ||
[self.screenShotsList removeLastObject]; | ||
|
||
dispatch_async(dispatch_get_main_queue(), ^{ | ||
[[NSNotificationCenter defaultCenter] postNotificationName:MHTabBarControllerViewControllerPopNotification object:nil]; | ||
}); | ||
|
||
return [super popViewControllerAnimated:animated]; | ||
} | ||
- (UIInterfaceOrientation)navigationControllerPreferredInterfaceOrientationForPresentation:(UINavigationController *)navigationController | ||
|
||
#pragma mark - Utility Methods - | ||
|
||
// get the current view screen shot | ||
- (UIImage *)capture | ||
{ | ||
NSLog(@"~~~~~~~~~~~~%s", __PRETTY_FUNCTION__); | ||
UIGraphicsBeginImageContextWithOptions(TOP_VIEW.bounds.size, TOP_VIEW.opaque, 0.0); | ||
[TOP_VIEW.layer renderInContext:UIGraphicsGetCurrentContext()]; | ||
|
||
UIImage * img = UIGraphicsGetImageFromCurrentImageContext(); | ||
|
||
UIGraphicsEndImageContext(); | ||
|
||
return img; | ||
} | ||
|
||
- (id <UIViewControllerInteractiveTransitioning>)navigationController:(UINavigationController *)navigationController | ||
interactionControllerForAnimationController:(id <UIViewControllerAnimatedTransitioning>) animationController | ||
// set lastScreenShotView 's position and alpha when paning | ||
- (void)moveViewWithX:(float)x | ||
{ | ||
NSLog(@"~~~~~~~~~~~~%s", __PRETTY_FUNCTION__); | ||
x = x>320?320:x; | ||
x = x<0?0:x; | ||
|
||
CGRect frame = TOP_VIEW.frame; | ||
frame.origin.x = x; | ||
TOP_VIEW.frame = frame; | ||
|
||
float scale = (x/6400)+0.95; | ||
float alpha = 0.4 - (x/800); | ||
|
||
lastScreenShotView.transform = CGAffineTransformMakeScale(scale, scale); | ||
blackMask.alpha = alpha; | ||
|
||
} | ||
|
||
- (id <UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController | ||
animationControllerForOperation:(UINavigationControllerOperation)operation | ||
fromViewController:(UIViewController *)fromVC | ||
toViewController:(UIViewController *)toVC | ||
{ | ||
NSLog(@"~~~~~~~~~~~~%s", __PRETTY_FUNCTION__); | ||
}*/ | ||
#pragma mark - UIGestureRecognizerDelegate | ||
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch { | ||
if (self.viewControllers.count <= 1 || !self.canDragBack) return NO; | ||
|
||
return YES; | ||
} | ||
|
||
/* | ||
#pragma mark - Navigation | ||
#pragma mark - Gesture Recognizer - | ||
|
||
// In a storyboard-based application, you will often want to do a little preparation before navigation | ||
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { | ||
// Get the new view controller using [segue destinationViewController]. | ||
// Pass the selected object to the new view controller. | ||
- (void)paningGestureReceive:(UIPanGestureRecognizer *)recoginzer | ||
{ | ||
// If the viewControllers has only one vc or disable the interaction, then return. | ||
if (self.viewControllers.count <= 1 || !self.canDragBack) return; | ||
|
||
// we get the touch position by the window's coordinate | ||
CGPoint touchPoint = [recoginzer locationInView:KEY_WINDOW]; | ||
|
||
// begin paning, show the backgroundView(last screenshot),if not exist, create it. | ||
if (recoginzer.state == UIGestureRecognizerStateBegan) { | ||
|
||
_isMoving = YES; | ||
startTouch = touchPoint; | ||
|
||
if (!self.backgroundView) | ||
{ | ||
CGRect frame = TOP_VIEW.frame; | ||
|
||
self.backgroundView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, frame.size.width , frame.size.height)]; | ||
[TOP_VIEW.superview insertSubview:self.backgroundView belowSubview:TOP_VIEW]; | ||
|
||
blackMask = [[UIView alloc]initWithFrame:CGRectMake(0, 0, frame.size.width , frame.size.height)]; | ||
blackMask.backgroundColor = [UIColor blackColor]; | ||
[self.backgroundView addSubview:blackMask]; | ||
} | ||
|
||
self.backgroundView.hidden = NO; | ||
|
||
if (lastScreenShotView) [lastScreenShotView removeFromSuperview]; | ||
|
||
UIImage *lastScreenShot = [self.screenShotsList lastObject]; | ||
lastScreenShotView = [[UIImageView alloc]initWithImage:lastScreenShot]; | ||
[self.backgroundView insertSubview:lastScreenShotView belowSubview:blackMask]; | ||
|
||
//End paning, always check that if it should move right or move left automatically | ||
}else if (recoginzer.state == UIGestureRecognizerStateEnded){ | ||
|
||
if (touchPoint.x - startTouch.x > 50) | ||
{ | ||
[UIView animateWithDuration:0.3 animations:^{ | ||
[self moveViewWithX:320]; | ||
} completion:^(BOOL finished) { | ||
|
||
[self popViewControllerAnimated:NO]; | ||
CGRect frame = TOP_VIEW.frame; | ||
frame.origin.x = 0; | ||
TOP_VIEW.frame = frame; | ||
|
||
_isMoving = NO; | ||
self.backgroundView.hidden = YES; | ||
|
||
}]; | ||
} | ||
else | ||
{ | ||
[UIView animateWithDuration:0.3 animations:^{ | ||
[self moveViewWithX:0]; | ||
} completion:^(BOOL finished) { | ||
_isMoving = NO; | ||
self.backgroundView.hidden = YES; | ||
}]; | ||
|
||
} | ||
return; | ||
|
||
// cancal panning, alway move to left side automatically | ||
}else if (recoginzer.state == UIGestureRecognizerStateCancelled){ | ||
|
||
[UIView animateWithDuration:0.3 animations:^{ | ||
[self moveViewWithX:0]; | ||
} completion:^(BOOL finished) { | ||
_isMoving = NO; | ||
self.backgroundView.hidden = YES; | ||
}]; | ||
|
||
return; | ||
} | ||
|
||
// it keeps move with touch | ||
if (_isMoving) { | ||
[self moveViewWithX:touchPoint.x - startTouch.x]; | ||
} | ||
} | ||
*/ | ||
|
||
@end |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Oops, something went wrong.