Skip to content

Commit

Permalink
modify navigation
Browse files Browse the repository at this point in the history
  • Loading branch information
jkcmcby committed Nov 25, 2014
1 parent 82203d8 commit 86dd3a7
Show file tree
Hide file tree
Showing 8 changed files with 372 additions and 70 deletions.
30 changes: 12 additions & 18 deletions MHCustomTabBarController/MHCustomTabBarController.m
Original file line number Diff line number Diff line change
Expand Up @@ -40,43 +40,37 @@ - (void)viewDidLoad {
[super viewDidLoad];

self.viewControllersByIdentifier = [NSMutableDictionary dictionary];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(newViewControllerWillShow:) name:MHNavigationControllerViewControllerWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(newViewControllerDidShow:) name:MHNavigationControllerViewControllerDidShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(pushViewController:) name:MHTabBarControllerViewControllerPushNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(popViewController:) name:MHTabBarControllerViewControllerPopNotification object:nil];
}

- (void)newViewControllerWillShow:(NSNotification *)noti
- (void)pushViewController:(NSNotification *)noti
{
UIViewController *notiViewController = noti.object;
MHNavigationController *nav = (MHNavigationController *)self.destinationViewController;
UIViewController *rootViewController = [[nav viewControllers] objectAtIndex:0];
if (![notiViewController isEqual:rootViewController]) {
[rootViewController.view addSubview:self.tabbar];
} else {

}
[self tabbarConstraint];

}

- (void)tabbarConstraint
- (void)popViewController:(NSNotification *)noti
{
self.tabbar.translatesAutoresizingMaskIntoConstraints = NO;
NSLayoutConstraint *constraint1 = [NSLayoutConstraint constraintWithItem:self.tabbar attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.tabbar.superview attribute:NSLayoutAttributeBottom multiplier:1 constant:0];
[self.tabbar.superview addConstraint:constraint1];
}

- (void)newViewControllerDidShow:(NSNotification *)noti
{
UIViewController *notiViewController = noti.object;
MHNavigationController *nav = (MHNavigationController *)self.destinationViewController;
UIViewController *rootViewController = [[nav viewControllers] objectAtIndex:0];

if ([notiViewController isEqual:rootViewController]) {
if ([[nav viewControllers] count] <= 1) {
[self.view addSubview:self.tabbar];
}
[self tabbarConstraint];
}

- (void)tabbarConstraint
{
self.tabbar.translatesAutoresizingMaskIntoConstraints = NO;
NSLayoutConstraint *constraint1 = [NSLayoutConstraint constraintWithItem:self.tabbar attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.tabbar.superview attribute:NSLayoutAttributeBottom multiplier:1 constant:0];
[self.tabbar.superview addConstraint:constraint1];
}

-(void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];

Expand Down
16 changes: 9 additions & 7 deletions MHCustomTabBarController/MHNavigationController.h
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
258 changes: 220 additions & 38 deletions MHCustomTabBarController/MHNavigationController.m
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
Binary file added MHCustomTabBarController/[email protected]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 86dd3a7

Please sign in to comment.