mirror of
https://github.com/zhigang1992/MultiLayerNavigation.git
synced 2026-05-11 06:53:51 +08:00
209 lines
6.0 KiB
Objective-C
209 lines
6.0 KiB
Objective-C
//
|
|
// MLNavigationController.m
|
|
// MultiLayerNavigation
|
|
//
|
|
// Created by Feather Chan on 13-4-12.
|
|
// Copyright (c) 2013年 Feather Chan. All rights reserved.
|
|
//
|
|
|
|
#define KEY_WINDOW [[UIApplication sharedApplication]keyWindow]
|
|
|
|
#import "MLNavigationController.h"
|
|
#import <QuartzCore/QuartzCore.h>
|
|
|
|
@interface MLNavigationController ()
|
|
{
|
|
CGPoint startTouch;
|
|
|
|
UIImageView *lastScreenShotView;
|
|
UIView *blackMask;
|
|
}
|
|
|
|
@property (nonatomic,retain) UIView *backgroundView;
|
|
@property (nonatomic,retain) NSMutableArray *screenShotsList;
|
|
|
|
@end
|
|
|
|
@implementation MLNavigationController
|
|
|
|
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
|
|
{
|
|
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
|
|
if (self) {
|
|
// Custom initialization
|
|
|
|
self.screenShotsList = [[[NSMutableArray alloc]initWithCapacity:2]autorelease];
|
|
self.canDragBack = YES;
|
|
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void)dealloc
|
|
{
|
|
self.screenShotsList = nil;
|
|
|
|
[self.backgroundView removeFromSuperview];
|
|
self.backgroundView = nil;
|
|
|
|
|
|
[super dealloc];
|
|
}
|
|
|
|
- (void)viewDidLoad
|
|
{
|
|
[super viewDidLoad];
|
|
// Do any additional setup after loading the view.
|
|
|
|
// 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;
|
|
|
|
UIImageView *shadowImageView = [[[UIImageView alloc]initWithImage:[UIImage imageNamed:@"leftside_shadow_bg"]]autorelease];
|
|
shadowImageView.frame = CGRectMake(-10, 0, 10, self.view.frame.size.height);
|
|
[self.view addSubview:shadowImageView];
|
|
|
|
UIPanGestureRecognizer *recognizer = [[[UIPanGestureRecognizer alloc]initWithTarget:self
|
|
action:@selector(paningGestureReceive:)]autorelease];
|
|
[recognizer delaysTouchesBegan];
|
|
[self.view addGestureRecognizer:recognizer];
|
|
}
|
|
|
|
- (void)didReceiveMemoryWarning
|
|
{
|
|
[super didReceiveMemoryWarning];
|
|
// Dispose of any resources that can be recreated.
|
|
}
|
|
|
|
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
|
|
{
|
|
[self.screenShotsList addObject:[self capture]];
|
|
|
|
[super pushViewController:viewController animated:animated];
|
|
}
|
|
|
|
- (UIViewController *)popViewControllerAnimated:(BOOL)animated
|
|
{
|
|
[self.screenShotsList removeLastObject];
|
|
|
|
return [super popViewControllerAnimated:animated];
|
|
}
|
|
|
|
#pragma mark - Utility Methods -
|
|
|
|
// get the current view screen shot
|
|
- (UIImage *)capture
|
|
{
|
|
UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, self.view.opaque, 0.0);
|
|
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
|
|
|
|
UIImage * img = UIGraphicsGetImageFromCurrentImageContext();
|
|
|
|
UIGraphicsEndImageContext();
|
|
|
|
return img;
|
|
}
|
|
|
|
- (void)moveViewWithX:(float)x
|
|
{
|
|
NSLog(@"Move to:%f",x);
|
|
x = x>320?320:x;
|
|
x = x<0?0:x;
|
|
|
|
CGRect frame = self.view.frame;
|
|
frame.origin.x = x;
|
|
self.view.frame = frame;
|
|
|
|
float scale = (x/6400)+0.95;
|
|
float alpha = 0.4 - (x/800);
|
|
|
|
lastScreenShotView.transform = CGAffineTransformMakeScale(scale, scale);
|
|
blackMask.alpha = alpha;
|
|
|
|
}
|
|
|
|
#pragma mark - Gesture Recognizer -
|
|
|
|
- (void)paningGestureReceive:(UIPanGestureRecognizer *)recoginzer
|
|
{
|
|
if (self.viewControllers.count <= 1 || !self.canDragBack) return;
|
|
|
|
CGPoint touchPoint = [recoginzer locationInView:KEY_WINDOW];
|
|
|
|
if (recoginzer.state == UIGestureRecognizerStateBegan) {
|
|
|
|
_isMoving = YES;
|
|
startTouch = touchPoint;
|
|
|
|
if (!self.backgroundView)
|
|
{
|
|
CGRect frame = self.view.frame;
|
|
|
|
self.backgroundView = [[[UIView alloc]initWithFrame:CGRectMake(0, 0, frame.size.width , frame.size.height)]autorelease];
|
|
[self.view.superview insertSubview:self.backgroundView belowSubview:self.view];
|
|
|
|
blackMask = [[[UIView alloc]initWithFrame:CGRectMake(0, 0, frame.size.width , frame.size.height)]autorelease];
|
|
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]autorelease];
|
|
[self.backgroundView insertSubview:lastScreenShotView belowSubview:blackMask];
|
|
|
|
}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 = self.view.frame;
|
|
frame.origin.x = 0;
|
|
self.view.frame = frame;
|
|
|
|
_isMoving = NO;
|
|
}];
|
|
}
|
|
else
|
|
{
|
|
[UIView animateWithDuration:0.3 animations:^{
|
|
[self moveViewWithX:0];
|
|
} completion:^(BOOL finished) {
|
|
_isMoving = NO;
|
|
self.backgroundView.hidden = YES;
|
|
}];
|
|
|
|
}
|
|
return;
|
|
|
|
}else if (recoginzer.state == UIGestureRecognizerStateCancelled){
|
|
|
|
[UIView animateWithDuration:0.3 animations:^{
|
|
[self moveViewWithX:0];
|
|
} completion:^(BOOL finished) {
|
|
_isMoving = NO;
|
|
self.backgroundView.hidden = YES;
|
|
}];
|
|
|
|
return;
|
|
}
|
|
|
|
if (_isMoving) {
|
|
[self moveViewWithX:touchPoint.x - startTouch.x];
|
|
}
|
|
}
|
|
|
|
@end
|