Apple提供的导航条是用来管理窗口控制器的结构的,某个UINavigationController执行Push操作后,该导航控制器管理的controllers共用一个导航条,如果对该导航条进行自定义,那么各个界面的导航条都会变成自定义以后的样式。但是,实际开发中,我们可能需要为不同的控制器定制不同的导航条。
第一种是使用自定义navigationBar.淘宝,网易新闻,达令等使用的是这种. 第二种是用截图的办法,在push到下一个页面时,截取屏幕,在使用edgePan来pop时看到的就是背后的截图,也能实现这种效果.京东,天猫等使用的是这种. 第三种是使用了一种比较特别,比较巧妙的办法实现的,也就是网易云音乐的实现方法,后面会分析一下这种实现. 第三种实现请去 http://www.jianshu.com/p/88bc827f0692/comments/4184624#comment-4184624查看
本文主要介绍第二种实现方案
http://blog.csdn.net/wzios/article/details/52527518 下拉隐藏显示请去看另一篇文章
1.自定义导航控制 (直接粘贴代码到控制器去研究) #import "WZNavigationController.h" @interface WZNavigationController ()<UIGestureRecognizerDelegate> /**存放每一个控制器的全屏截图 */ @property (nonatomic,strong) NSMutableArray *images; @property (nonatomic,strong) UIImageView *lastVcView; @property (nonatomic,strong) UIView *cover; @end @implementation WZNavigationController - (UIImageView *)lastVcView { if (!_lastVcView) { UIWindow *window = [UIApplication sharedApplication].keyWindow; UIImageView *lastVcView = [[UIImageView alloc] init]; // lastVcView.frame = window.bounds; lastVcView.frame = CGRectMake(-window.frame.size.width,0,window.frame.size.width,window.frame.size.height); self.lastVcView = lastVcView; } return _lastVcView; } - (UIView *)cover { if (!_cover) { UIWindow *window = [UIApplicationsharedApplication].keyWindow; UIView *cover = [[UIViewalloc]init]; cover.backgroundColor = [UIColorblackColor]; cover.frame = window.bounds; cover.alpha =0.3; self.cover = cover; } return_cover; } - (NSMutableArray *)images { if (!_images) { self.images = [[NSMutableArrayalloc]init]; } return_images; } - (void)viewDidLoad { [superviewDidLoad]; //自带的边缘滑动边缘滑动 // self.interactivePopGestureRecognizer.enabled = NO; // self.interactivePopGestureRecognizer.delegate = self; //自定义边缘滑动手势替代系统的 UIScreenEdgePanGestureRecognizer *recognizer = [[UIScreenEdgePanGestureRecognizeralloc]initWithTarget:selfaction:@selector(dragging:)]; recognizer.edges =UIRectEdgeLeft; [self.viewaddGestureRecognizer:recognizer]; } -(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch { returnself.childViewControllers.count>1; } - (void)dragging:(UIPanGestureRecognizer *)recognizer { //如果只有1个子控制器,停止拖拽 if (self.viewControllers.count <=1)return; //在x方向上移动的距离 CGFloat tx = [recognizer translationInView:self.view].x; if (tx <0)return; //添加截图到最后面 if (recognizer.state == UIGestureRecognizerStateEnded || recognizer.state == UIGestureRecognizerStateCancelled) { // 决定pop还是还原 CGFloat x = self.view.frame.origin.x; if (x >=self.view.frame.size.width *0.5) { [UIView animateWithDuration:0.25 animations:^{ self.view.transform = CGAffineTransformMakeTranslation(self.view.frame.size.width,0); self.lastVcView.transform = CGAffineTransformMakeTranslation(self.view.frame.size.width,0); } completion:^(BOOL finished) { [self popViewControllerAnimated:NO]; [self.lastVcView removeFromSuperview]; [self.cover removeFromSuperview]; self.view.transform = CGAffineTransformIdentity; [self.images removeLastObject]; }]; } else { [UIView animateWithDuration:0.25 animations:^{ self.view.transform = CGAffineTransformIdentity; self.lastVcView.transform = CGAffineTransformIdentity; }]; } } else { // 移动view self.view.transform = CGAffineTransformMakeTranslation(tx,0); UIWindow *window = [UIApplication sharedApplication].keyWindow; self.lastVcView.image =self.images[self.images.count -1]; [window insertSubview:self.lastVcView atIndex:0]; // [window insertSubview:self.cover aboveSubview:self.lastVcView]; self.lastVcView.transform = CGAffineTransformMakeTranslation(tx,0); } } /** * 产生截图 */ - (void)createScreenShot { UIGraphicsBeginImageContextWithOptions(self.view.frame.size,YES,0.0); [self.view.layer renderInContext:UIGraphicsGetCurrentContext()]; UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); [self.images addObject:image]; } - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated { if (self.childViewControllers.count >0) {//如果push进来的不是第一个控制器 [self createScreenShot]; UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; [button setTitle:@"返回" forState:UIControlStateNormal]; [button setImage:[UIImage imageNamed:@"arrow"] forState:UIControlStateNormal]; button.frame = CGRectMake(0,0,70,30); button.imageEdgeInsets = UIEdgeInsetsMake(0,0,0,10); button.contentEdgeInsets = UIEdgeInsetsMake(0, -10,0,0); [button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; [button addTarget:self action:@selector(back) forControlEvents:UIControlEventTouchUpInside]; viewController.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:button]; // 隐藏tabbar viewController.hidesBottomBarWhenPushed =YES; // //另外一种解决自定义返回按钮边缘滑动失效的问题如果自定义返回按钮后,边缘滑动返回可能失效,需要添加下面的代码 // __weak typeof(viewController)Weakself = viewController; // self.interactivePopGestureRecognizer.delegate = (id)Weakself; } // 这句super的push要放在后面,让viewController可以覆盖上面设置的leftBarButtonItem [super pushViewController:viewController animated:animated]; } - (void)back { [self popViewControllerAnimated:YES]; } @end
2.然后在对应的控制器的 viewWillAppear恢复导航栏对应的颜色,就不会出现边缘滑动因为导航栏样式不同而出现的诡异行为。