// // MLNavigationController.m // MultiLayerNavigation // // Created by Feather Chan on 13-4-12. // Copyright (c) 2013年 Feather Chan. All rights reserved. // #import "MLNavigationController.h" #import #import "commentAndAskController.h" #import "detailContentHomeController.h" #import "DescView.h" //#import "LCAlertView.h" #define rectWidth rect_screen.size.width @interface MLNavigationController () { CGPoint startTouch; UIImageView *lastScreenShotView; UIView *blackMask; float lastTouchX; } @property (nonatomic,retain) UIView *backgroundView; @property (nonatomic,retain) NSMutableArray *screenShotsList; @property (nonatomic,assign) BOOL isMoving; @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; lastTouchX = 1000; } return self; } //- (id)initWithRootViewController:(UIViewController *)rootViewController { // self = [super initWithRootViewController:rootViewController]; // if (self) { // // self.screenShotsList = [[[NSMutableArray alloc]initWithCapacity:2]autorelease]; // self.canDragBack = YES; // lastTouchX = 1000; // } // return self; //} - (void)dealloc { self.screenShotsList = nil; [self.backgroundView removeFromSuperview]; self.backgroundView = nil; TPLOG(@"=====dealloc:%@=====",self.description); [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, TOP_VIEW.frame.size.height); [TOP_VIEW addSubview:shadowImageView]; UIPanGestureRecognizer *recognizer = [[[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(paningGestureReceive:)]autorelease]; recognizer.delegate = self; [recognizer delaysTouchesBegan]; [self.view addGestureRecognizer:recognizer]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:(BOOL)animated]; if (self.screenShotsList.count == 0) { UIImage *capturedImage = [self capture]; if (capturedImage) { [self.screenShotsList addObject:capturedImage]; } } } - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [MobClick beginLogPageView:@"PageOne"]; } - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; [MobClick endLogPageView:@"PageOne"]; } // override the push method - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated { if ([(TPWindow*)KEY_WINDOW respondsToSelector:@selector(closeAndSotoEmbeddedVideo)]) { [(TPWindow*)KEY_WINDOW closeAndSotoEmbeddedVideo]; [(TPWindow*)KEY_WINDOW enabelEmbeddedVideoGesture:NO withVideoController:nil embeddedRect:CGRectZero]; } /** * bug:6188(【倒退】个人主页:个人主页点击头像选择查看头像闪退) */ self.canDragBack = YES; UIImage *capturedImage = [self capture]; if (capturedImage) { [self.screenShotsList addObject:capturedImage]; } // [[UIApplication sharedApplication] beginIgnoringInteractionEvents]; // // if (isNotIOS8) { // if (self.viewControllers.count > 1) { // NSMutableArray *tempStack = [NSMutableArray arrayWithArray:self.viewControllers]; // __block BOOL isHaveSame = NO; // __block NSInteger firstDetailConetentController; // [self.viewControllers enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { // if ([obj isKindOfClass:[detailContentHomeController class]]) { // firstDetailConetentController = idx; // *stop = YES; // } // }]; // // [self.viewControllers enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { // if ([obj isKindOfClass:[viewController.class class]]) { // if (![viewController isKindOfClass:[detailContentHomeController class]] // || idx != firstDetailConetentController) {//4322: 【需求】相关新闻:相关新闻作为独立页面可以保存一层 // [tempStack removeObjectAtIndex:idx]; // [self.screenShotsList removeObjectAtIndex:idx+1]; // isHaveSame = YES; // } // } // }]; // if (isHaveSame) { // self.viewControllers = [NSArray arrayWithArray:tempStack]; // } // } // } [super pushViewController:viewController animated:animated]; // if (isIOS8) { // if (self.viewControllers.count > 1) { // NSMutableArray *tempStack = [NSMutableArray arrayWithArray:self.viewControllers]; // __block BOOL isHaveSame = NO; // __block NSInteger firstDetailConetentController; // [self.viewControllers enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { // if ([obj isKindOfClass:[detailContentHomeController class]]) { // firstDetailConetentController = idx; // *stop = YES; // } // }]; // // [self.viewControllers enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { // if (idx != self.viewControllers.count-1) { // if ([obj isKindOfClass:[viewController.class class]]) { // if ([obj isKindOfClass:[viewController.class class]]) { // if (![viewController isKindOfClass:[detailContentHomeController class]] // || idx != firstDetailConetentController) {//4322: 【需求】相关新闻:相关新闻作为独立页面可以保存一层 // [tempStack removeObjectAtIndex:idx]; // [self.screenShotsList removeObjectAtIndex:idx+1]; // isHaveSame = YES; // } // } // } // } // }]; // if (isHaveSame) { // self.viewControllers = [NSArray arrayWithArray:tempStack]; // } // } // } // [[UIApplication sharedApplication] endIgnoringInteractionEvents]; } // override the pop method - (UIViewController *)popViewControllerAnimated:(BOOL)animated { TPLOG(@"===========pop==========="); [self.screenShotsList removeLastObject]; [[NSNotificationCenter defaultCenter] postNotificationName:CONTENTDETAILPOPBACK object:nil]; self.canDragBack = YES; return [super popViewControllerAnimated:animated]; } - (UIViewController*)popBackWithTopSwipeGesture { [self.screenShotsList removeLastObject]; self.canDragBack = YES; return [super popViewControllerAnimated:NO]; } #pragma mark - Utility Methods - // get the current view screen shot - (UIImage *)capture { if ([TOP_VIEW isKindOfClass:[UIImageView class]]) { return ((UIImageView*)TOP_VIEW).image; } UIGraphicsBeginImageContextWithOptions(TOP_VIEW.bounds.size, TOP_VIEW.opaque, 0.0); [TOP_VIEW.layer renderInContext:UIGraphicsGetCurrentContext()]; UIImage * img = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return img; } // set lastScreenShotView 's position and alpha when paning - (void)moveViewWithX:(float)x panRec:(UIPanGestureRecognizer*)recoginzer { if (lastTouchX == 1000) { lastTouchX = x; } x = x>rectWidth?rectWidth:x; x = x<0?0:x; if (x != rectWidth) { CGPoint offset = [recoginzer translationInView:KEY_WINDOW]; CGRect shotFrame = lastScreenShotView.frame; if (x != 0) { CGRect frame = TOP_VIEW.frame; frame.origin.x = x; TOP_VIEW.frame = frame; shotFrame.origin.x = shotFrame.origin.x + offset.x/2; }else { CGRect frame = TOP_VIEW.frame; frame.origin.x = x; TOP_VIEW.frame = frame; if (lastTouchX < 0) { shotFrame.origin.x = shotFrame.origin.x - lastTouchX; }else { shotFrame.origin.x = shotFrame.origin.x - lastTouchX/2; } } lastScreenShotView.frame = shotFrame; blackMask.alpha = 0; lastTouchX = x; [recoginzer setTranslation:CGPointMake(0, 0) inView:KEY_WINDOW]; }else { CGRect frame = TOP_VIEW.frame; frame.origin.x = x; TOP_VIEW.frame = frame; lastTouchX = 1000; lastScreenShotView.frame = CGRectMake(0, 0, blackMask.frame.size.width , blackMask.frame.size.height); } } #pragma mark - UIGestureRecognizerDelegate - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch { if (self.viewControllers.count <= 1 || !self.canDragBack) return NO; return YES; } #pragma mark - Gesture Recognizer - - (void)paningGestureReceive:(UIPanGestureRecognizer *)recoginzer { UIMenuController *menu = [UIMenuController sharedMenuController]; if (menu.menuVisible) { [menu setMenuVisible:NO animated:YES]; } // 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)]autorelease]; [TOP_VIEW.superview insertSubview:self.backgroundView belowSubview:TOP_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 = nil; UIImage *lastScreenShot = [self.screenShotsList lastObject]; lastScreenShotView = [[UIImageView alloc]initWithImage:lastScreenShot]; [self.backgroundView insertSubview:lastScreenShotView belowSubview:blackMask]; lastScreenShotView.frame = CGRectMake(-blackMask.frame.size.width/2, 0, blackMask.frame.size.width , blackMask.frame.size.height); //End paning, always check that if it should move right or move left automatically }else if (recoginzer.state == UIGestureRecognizerStateEnded){ if (touchPoint.x - startTouch.x > 100) { [UIView animateWithDuration:0.3 animations:^{ [self moveViewWithX:rectWidth panRec:recoginzer]; } completion:^(BOOL finished) { [self popViewControllerAnimated:NO]; CGRect frame = TOP_VIEW.frame; frame.origin.x = 0; TOP_VIEW.frame = frame; if (lastScreenShotView) { [self.backgroundView.subviews enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { if ([obj isEqual:lastScreenShotView]) { [lastScreenShotView removeFromSuperview]; } }]; } _isMoving = NO; self.backgroundView.hidden = YES; }]; } else { [UIView animateWithDuration:0.3 animations:^{ [self moveViewWithX:0 panRec:recoginzer]; } completion:^(BOOL finished) { if (lastScreenShotView) { [self.backgroundView.subviews enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { if ([obj isEqual:lastScreenShotView]) { [lastScreenShotView removeFromSuperview]; } }]; } _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 panRec:recoginzer]; } completion:^(BOOL finished) { _isMoving = NO; self.backgroundView.hidden = YES; }]; return; } // it keeps move with touch if (_isMoving) { [self moveViewWithX:touchPoint.x - startTouch.x panRec:recoginzer]; } } #pragma mark - rotate - (BOOL)shouldAutorotate { return [self.viewControllers.lastObject shouldAutorotate]; } - (UIInterfaceOrientationMask)supportedInterfaceOrientations { return [self.viewControllers.lastObject supportedInterfaceOrientations]; } - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation { if ([self.viewControllers.lastObject respondsToSelector:@selector(preferredInterfaceOrientationForPresentation)]) { return [self.viewControllers.lastObject preferredInterfaceOrientationForPresentation]; }else { return UIInterfaceOrientationPortrait; } } @end