Files
MultiLayerNavigation/Src/MLNavigationController.m
2013-04-18 19:12:29 +08:00

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