iOS实现导航栏透明示例代码 2017-04-08 来源:网络 字号:大 中 小 我要评论 收藏本文
在最近一个项目中碰到这样一个场景,在被push进来的一个页面设置导航栏透明,且要求控制对tableview组的头视图进行悬停显示,nav随着tableview偏移量改变透明度,当然这样的需求确实不是什么难事,但是如果当前页面继续push一个不需要此类效果的页面,当在返回当前页面的时候就会出现一个坑,nav的展示很突兀,下面是直接上解决方法...ps:假设A页面为需要设置透明,B页面被Apush且不需要设置透明 首先在需要设置导航栏透明的页面的viewDidload中写上 self.title = @"Title"; [self.navigationController.navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault]; self.navigationController.navigationBar.shadowImage = [UIImage new]; self.barImageView = self.navigationController.navigationBar.subviews.firstObject; self.barImageView.alpha = 0; //设置状态栏 [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent]; //设置标题颜色 self.navigationController.navigationBar.titleTextAttributes = @{NSForegroundColorAttributeName : [UIColor clearColor]}; 在scrollViewDidScroll代理方法中 -(void)scrollViewDidScroll:(UIScrollView *)scrollView { CGFloat offset = scrollView.contentOffset.y; //根据自己需要设置(136)的大小 CGFloat alpha = offset / 136; _barImageView.alpha = alpha; //记录下当前的透明度,在返回当前页面时需要 _alpha = alpha; [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithFloat:alpha] forKey:@"_alpha"]; //设置标题的透明度 self.navigationController.navigationBar.titleTextAttributes = @{NSForegroundColorAttributeName : [UIColor colorWithWhite:0 alpha:alpha]}; } 当前页的viewWillAppear, viewDidAppear, viewWillDisappear -(void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; self.table.delegate = self; } -(void)viewDidAppear:(BOOL)animated { BOOL isGesturePop = [[[NSUserDefaults standardUserDefaults] objectForKey:@"isGesturePop"] boolValue]; if (!isGesturePop) { _barImageView.alpha = _alpha; self.navigationController.navigationBar.titleTextAttributes = @{NSForegroundColorAttributeName : [UIColor colorWithWhite:0 alpha:_alpha]}; } [super viewDidAppear:animated]; } -(void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; self.table.delegate = nil; self.navigationController.navigationBar.titleTextAttributes = @{NSForegroundColorAttributeName : [UIColor blackColor]}; _barImageView.alpha = 1; [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithBool:NO] forKey:@"isGesturePop"]; } 那么在我们需要push的下一个页面需要什么操作呢,我们需要在这个页面显示正常的nav并且禁掉系统的手势pop,自己写一个pop手势,以方便我们拿到pop滑动时的偏移量,在做的时候使用了两个类,在最后会有源码贴出 B.m 须遵守UIGestureRecognizerDelegate,并导入NavigationInteractiveTransition.h 全局变量 @property (nonatomic, strong) NavigationInteractiveTransition *navT; viewDidLoad self.navigationController.interactivePopGestureRecognizer.enabled = NO; UIGestureRecognizer *gesture = self.navigationController.interactivePopGestureRecognizer; gesture.enabled = NO; UIView *gestureView = gesture.view; UIPanGestureRecognizer *popRecognizer = [[UIPanGestureRecognizer alloc] init]; popRecognizer.delegate = self; popRecognizer.maximumNumberOfTouches = 1; [gestureView addGestureRecognizer:popRecognizer]; _navT = [[NavigationInteractiveTransition alloc] initWithViewController:self.navigationController]; [popRecognizer addTarget:_navT action:@selector(handleControllerPop:)]; UIGestureRecognizerDelegate 代理方法gestureRecognizerShouldBegin - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer { //记录当前是是否是通过手势滑动回去 [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithBool:YES] forKey:@"isGesturePop"]; /** * 这里有两个条件不允许手势执行,1、当前控制器为根控制器;2、如果这个push、pop动画正在执行(私有属性) */ return self.navigationController.viewControllers.count != 1 && ![[self.navigationController valueForKey:@"_isTransitioning"] boolValue]; } 需要依赖的两个类源码 NavigationInteractiveTransition.h #import <UIKit/UIKit.h> @class UIViewController, UIPercentDrivenInteractiveTransition; @interface NavigationInteractiveTransition : NSObject <UINavigationControllerDelegate> - (instancetype)initWithViewController:(UIViewController *)vc; - (void)handleControllerPop:(UIPanGestureRecognizer *)recognizer; - (UIPercentDrivenInteractiveTransition *)interactivePopTransition; @end NavigationInteractiveTransition.m #import "NavigationInteractiveTransition.h" #import "PopAnimation.h" @interface NavigationInteractiveTransition () @property (nonatomic, weak) UINavigationController *vc; @property (nonatomic, strong) UIPercentDrivenInteractiveTransition *interactivePopTransition; @property(nonatomic, strong) UIImageView *barImageView; @end @implementation NavigationInteractiveTransition - (instancetype)initWithViewController:(UIViewController *)vc { self = [super init]; if (self) { self.vc = (UINavigationController *)vc; self.vc.delegate = self; } return self; } /** * 我们把用户的每次Pan手势操作作为一次pop动画的执行 */ - (void)handleControllerPop:(UIPanGestureRecognizer *)recognizer { /** * interactivePopTransition就是我们说的方法2返回的对象,我们需要更新它的进度来控制Pop动画的流程,我们用手指在视图中的位置与视图宽度比例作为它的进度。 */ CGFloat progress = [recognizer translationInView:recognizer.view].x / recognizer.view.bounds.size.width; [self.vc.navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault]; self.vc.navigationBar.shadowImage = [UIImage new]; self.barImageView = self.vc.navigationBar.subviews.firstObject; CGFloat alpha = [[[NSUserDefaults standardUserDefaults] objectForKey:@"_alpha"] floatValue]; self.barImageView.alpha = 1 - progress > alpha ? alpha : 1 - progress; // NSLog(@"===progress==%.2f",progress); /** * 稳定进度区间,让它在0.0(未完成)~1.0(已完成)之间 */ progress = MIN(1.0, MAX(0.0, progress)); if (recognizer.state == UIGestureRecognizerStateBegan) { /** * 手势开始,新建一个监控对象 */ self.interactivePopTransition = [[UIPercentDrivenInteractiveTransition alloc] init]; /** * 告诉控制器开始执行pop的动画 */ [self.vc popViewControllerAnimated:YES]; } else if (recognizer.state == UIGestureRecognizerStateChanged) { /** * 更新手势的完成进度 */ [self.interactivePopTransition updateInteractiveTransition:progress]; } else if (recognizer.state == UIGestureRecognizerStateEnded || recognizer.state == UIGestureRecognizerStateCancelled) { /** * 手势结束时如果进度大于一半,那么就完成pop操作,否则重新来过。 */ if (progress > 0.5) { [self.interactivePopTransition finishInteractiveTransition]; self.barImageView.alpha = 0;; } else { [self.interactivePopTransition cancelInteractiveTransition]; } self.interactivePopTransition = nil; } } - (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC { /** * 方法1中判断如果当前执行的是Pop操作,就返回我们自定义的Pop动画对象。 */ if (operation == UINavigationControllerOperationPop) return [[PopAnimation alloc] init]; return nil; } - (id<UIViewControllerInteractiveTransitioning>)navigationController:(UINavigationController *)navigationController interactionControllerForAnimationController:(id<UIViewControllerAnimatedTransitioning>)animationController { /** * 方法2会传给你当前的动画对象animationController,判断如果是我们自定义的Pop动画对象,那么就返回interactivePopTransition来监控动画完成度。 */ if ([animationController isKindOfClass:[PopAnimation class]]) return self.interactivePopTransition; return nil; } @end PopAnimation.h #import <Foundation/Foundation.h> #import <UIKit/UIKit.h> @interface PopAnimation : NSObject <UIViewControllerAnimatedTransitioning> @end PopAnimation.m #import "PopAnimation.h" @interface PopAnimation () @property (nonatomic, strong) id <UIViewControllerContextTransitioning> transitionContext; @end @implementation PopAnimation - (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext { //这个方法返回动画执行的时间 return 0.25; } /** * transitionContext你可以看作是一个工具,用来获取一系列动画执行相关的对象,并且通知系统动画是否完成等功能。 */ - (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext { /** * 获取动画来自的那个控制器 */ UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey]; /** * 获取转场到的那个控制器 */ UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey]; /** * 转场动画是两个控制器视图时间的动画,需要一个containerView来作为一个“舞台”,让动画执行。 */ UIView *containerView = [transitionContext containerView]; [containerView insertSubview:toViewController.view belowSubview:fromViewController.view]; NSTimeInterval duration = [self transitionDuration:transitionContext]; /** * 执行动画,我们让fromVC的视图移动到屏幕最右侧 */ [UIView animateWithDuration:duration animations:^{ fromViewController.view.transform = CGAffineTransformMakeTranslation([UIScreen mainScreen].bounds.size.width, 0); }completion:^(BOOL finished) { /** * 当你的动画执行完成,这个方法必须要调用,否则系统会认为你的其余任何操作都在动画执行过程中。 */ [transitionContext completeTransition:!transitionContext.transitionWasCancelled]; }]; } - (void)animationDidStop:(CATransition *)anim finished:(BOOL)flag { [_transitionContext completeTransition:!_transitionContext.transitionWasCancelled]; } @end 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。 |
相关热词搜索:
上一篇:IOS 基础之设置 tableview 的分割线
下一篇:最后一页
看完本文,您的心情是?
评论排行
- ·如何清除DNS缓存 使用命令清理dns缓存方法(2)
- ·Win8.1升级Win10遇到错误代码0xc190010...(1)
- ·Windows RT 8.1 Update 3九月发布 ...(0)
- ·如何将ubuntu安装到U盘实现即插即用(0)
- ·微软否认Xbox One有远程关闭开关(0)
- ·Surface Book详细拆解:千万不要自己动手修(0)
- ·WIN10免费升级正版手册(5分钟读懂WIN10...(0)
- ·你的今日头条账号为什么会被封?(0)
- ·win7电脑怎么翻墙看国外的网站?(0)
- ·shell脚本运行5秒后自动退出的代码(0)
- ·jsp 不支持EL表达式,解决办法(0)
- ·table合并单元格与img图片铺满整个td的html(0)
- ·Mac OS X 系统备份指南(0)
- ·Shell脚本注释写法(0)
- ·windows8激活码、序列号、激活密钥、激...(0)
- ·从一个不错的留言本弄的mysql数据库操作类(0)
- ·PHP漏洞全解(详细介绍)(0)
- ·phpBB BBcode处理的漏洞(0)
- ·安装Win10技术预览版有风险吗?win10预...(0)
- ·基于mysql的论坛(6)(0)
猜你喜欢
- ·iOS自定义collectionView实现毛玻璃效果
- ·iOS10 推送完整剖析和注意事项
- ·使用Xcode为iOS应用项目创建PCH文件的方法...
- ·学习iOS全局跑马灯
- ·iOS常用小功能(获得屏幕图像、压缩图片、...
- ·iOS App开发中的UIPageControl分页控件使...
- ·iOS实时监控网络状态的改变
- ·iOS 更改UILabel某些字体样式方法
- ·iOS 定制多样式二维码
- ·iOS 10 Today Widget解析
- ·iOS 进度条、加载、安装动画的简单实现
- ·详解iOS开发中的转场动画和组动画以及UIV...
- ·iOS自定义日历控件的简单实现过程
- ·IOS 开发之对象为空的判断(nil、null)详解
- ·iOS实现带动画的环形进度条
- ·iOS界面跳转时导航栏和tabBar的隐藏与显示...
热门推荐
- ·详解iOS通过ASIHTTPRequest提交JSON数据
- ·iOS App开发中使cell高度自适应的黑魔法详解
- ·IOS Xcode中快捷键大全
- ·谈谈制作iOS Ad-Hoc测试应用
- ·分享一个iOS下实现基本绘画板功能的简单方法
- ·iOS支付宝支付方法详解
- ·ios下移动文件方法汇总
- ·iOS 条码及二维码扫描(从相册中读取条形码/二维码)及扫码过程中遇到的坑
- ·iOS应用设计模式开发中对简单工厂和工厂方法模式的运用
- ·IOS UIWebView获取404、504等错误问题解决方案
- ·讲解Java中如何构造内部类对象以及访问对象
- ·IOS中UIWebView加载Loading的实现方法
- ·MacOS无法挂载NFS Operation not permitted错误解决办法
- ·实例讲解iOS中的UIPageViewController翻页视图控制器
- ·iOS图片拉伸的4种方法
本月排行
最近更新
- ·iOS实现导航栏透明示例代码
- ·IOS 基础之设置 tableview 的分割线
- ·IOS实现的简单画板功能
- ·IOS开发中加载大量网络图片优化方法
- ·iOS上下文实现评价星星示例代码
- ·react-native中AsyncStorage实例详解
- ·iOS archive保存图片到本地的方法
- ·iOS仿微信摇一摇动画效果加震动音效实例
- ·IOS本地日志记录解决方案
- ·iOS实现一个简易日历代码
- ·iOS获取当前连接的WiFi以及IP地址
- ·iOS常用小功能(获得屏幕图像、压缩图片、加边框、调整label的size)
- ·iOS页面跳转及数据传递(三种)
- ·iOS视频添加背景音乐同时保留原音
- ·iOS获取当前app的设备名称和版本号等内容
- ·IOS 远程通知兼容(IOS7,IOS8)实例详解
- ·IOS 中runtime使用方法整理
- ·iOS 定制多样式二维码
- ·iOS 二维码扫描和应用跳转
- ·iOS实现图片存在本地、再从本地获取图片的功能