导航栏协议方法UINavigationControllerDelegate
关于UINavigationControllerDelegate:
- Delegate中一共有6个方法。其中两个跟控制器ViewController的跳转有关、有两个跟屏幕的旋转有关、有两个跟导航栏动画有关(可以设计交互式或者非交互式的转场动画)。
前提配置:为了下面所说的测试都能如期的进行,有几个步骤是需要设置好的
1、声明UINavigationControllerDelegate协议
@interface ViewControllerOne () <UINavigationControllerDelegate>
2、遵守该协议
self.navigationController.delegate = self;
3、在遵守该协议的控制器中写出需要用到的协议方法
一、首先介绍下跟控制器的跳转相关的两个协议方法:
// Called when the navigation controller shows a new top view controller via a push, pop or setting of the view controller stack.
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
NSLog(@"~~~~~~~~~~willShowViewController");
} - (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
NSLog(@"~~~~~~~~~~didShowViewController");
}
说明:
1、当控制器push、pop、直接设置navigationController的controllers属性,都是可以触发这两个方法的。
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
ViewControllerTwo *vcTwo = [[ViewControllerTwo alloc] init];
// 可触发
[self.navigationController pushViewController:vcTwo animated:YES];
/* 不可触发
[self.view addSubview:vcTwo.view];
[self addChildViewController:vcTwo];
[vcTwo didMoveToParentViewController:self];
*/
/* 不可触发
[self presentViewController:vcTwo animated:YES completion:nil];
*/
/* 可触发
self.navigationController.viewControllers = @[self, vcTwo];
*/
}
2、为了能够准确的理解这两个方法,一定要记住这个是navigationController的协议方法。对它来说,即将进入这个控制器栈时调用willShow方法,已经进栈后调用didShow方法。
当vc1-push-vc2时,是vc2willShow、vc2didShow,
当vc2-pop-vc1时,是vc1willShow、vc1didShow。
3、因为navigationController自身、凡是进栈后的控制器都能够拿到navigationController这个对象,因此都可以成为它的代理。但是,有两个原则:
(1)始终以最新成为代理的为准。
(2)当最新成为代理的控制器销毁后(因为代理是weak,所以不会强留代理),第二新的代理成为接班者。
但是有个注意点:一个控制器销毁是在另一个控制器didShow之后,一个控制器成为接班者是在didShow之后。
举例如下:vc1、vc2都是navigationController的代理。过程是vc1-push-vc2,然后vc2-pop-vc1。
vc1-push-vc2的过程是:vc1是真代理、vc2willShow、vc2didshow、vc2成为真代理。
vc2-pop-vc1的过程是:vc2是真代理、vc1willShow、vc1didShow、vc1成为真代理。
二、然后介绍下跟屏幕的旋转有关的代理(真的不常用,而且真的比较坑)
首先要说明白的是,屏幕旋转有三个相关的地方:手机上的旋转开关、项目在Xcode上的配置、接下来要介绍的这2个协议方法。
// 返回-导航控制器支持的设备方向
// 每次旋转设备的时候询问(前提是iPhone上的屏幕旋转开关是开着的)
- (UIInterfaceOrientationMask)navigationControllerSupportedInterfaceOrientations:(UINavigationController *)navigationController {
NSLog(@"~~~~~设置方法设置导航控制器支持的设备方向~~~~~");
return UIInterfaceOrientationMaskAllButUpsideDown;
} // 这个方法设置导航控制器的首选设备方向
- (UIInterfaceOrientation)navigationControllerPreferredInterfaceOrientationForPresentation:(UINavigationController *)navigationController {
NSLog(@"~~~~~这个方法设置导航控制器的首选设备方向~~~~~");
return UIInterfaceOrientationLandscapeLeft;
}
现在表述下手机上的旋转开关、Xcode上的配置、协议方法、屏幕的方向四者之间的联系:
(1)当手机上的旋转开关关闭时,Xcode上的配置失效、当设备旋转时协议方法不调用、屏幕只能是竖屏显示。

(2)当手机上的旋转开关开着时,屏幕的可旋转方向由「Xcode上的配置」和「可旋转方向的协议方法」两者的交集决定。当设备旋转时,「可旋转方向的协议方法」被调用,屏幕会旋转成交集中存在的方向。
(3)至于屏幕最初显示的方向的依据现象是这样的:只要「Xcode上的配置」,包含Portrait方向(即竖屏),则最初显示的方向都是竖屏。只要「Xcode上的配置」不包含Portrait(即竖屏),则最初显示的方向就是设备往左(即屏幕往右)的方向(可以通过下面图像进行理解)。至于「首选设备方向的协议方法」一直不调用。在这种情况下,无关手机上的旋转开关的状态(不管开关,前面文字描述的内容依然成立)。

吐槽:
(1)虽然Xcode上的配置写的是“Device Orientation”,但是真实功能却是“可选方向”的作用。并且真实的可选方向,还必须是「Xcode上的配置」和「可旋转方向协议方法」两者的交集。
(2)「首选设备方向的协议方法」一直不被调用。
三、简介下跟导航栏转场动画相关的两个协议方法
// 没有交互的转场动画
- (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController
animationControllerForOperation:(UINavigationControllerOperation)operation
fromViewController:(UIViewController *)fromVC
toViewController:(UIViewController *)toVC {
NSLog(@"~~~~~~~~~~%ld~%@~%@", operation, fromVC.class, toVC.class);
return nil;
} // 有交互的转场动画
- (id<UIViewControllerInteractiveTransitioning>)navigationController:(UINavigationController *)navigationController
interactionControllerForAnimationController:(id<UIViewControllerAnimatedTransitioning>)animationController {
NSLog(@"~~~~~~~~~~%@", animationController);
return nil;
}
免责说明:
关于转场动画,不在该篇文章的讨论范围。其实也是因为内容比较多,后面在专门重起一文再议。
简单闲扯下:
1、转场动画可以分为交互式与非交互式,如果设置非交互式的用上面第一个协议方法就可以了。
2、第一个协议方法中的operation参数,可以知道当前进行的是push还是pop操作。
导航栏协议方法UINavigationControllerDelegate的更多相关文章
- Android (争取做到)最全的底部导航栏实现方法
本文(争取做到)Android 最全的底部导航栏实现方法. 现在写了4个主要方法. 还有一些个人感觉不完全切题的方法也会简单介绍一下. 方法一. ViewPager + List<View> ...
- zblog插件增加后台导航栏的方法
有时我们经常需要对插件进行设置,但是又不能让用户去做这些,那么下面的方法将会给插件增加在后台导航栏显示的功能 首先打开对应插件的文件夹,找到对应插件的 include.php 文件 将下面的代码粘 ...
- <iOS 导航栏>第一节:导航栏透明方法实现代码
说下导航栏的透明方法: 很多应用需要导航栏随着向上滑动,逐渐从透明变成不透明,很炫酷,大部分应用都在使用导航栏渐变效果,现附上代码然后直接将实现,一会讲下如何来实现,这一部分直接上代码. ...
- UIView显示时遮挡导航栏的方法
[self.navigationController.view:addSubview];
- CSS 导航栏
实例: 导航栏 Home News Articles Forum Contact About 导航栏 熟练使用导航栏,对于任何网站都非常重要. 使用CSS你可以转换成好看的导航栏而不是枯燥的HTML菜 ...
- NavUtils【底部虚拟导航栏工具类】
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 获取底部虚拟导航栏的高度值 效果图 代码分析 checkDeviceHasNavigationBar(Context context ...
- JS写的二级导航栏(利用冒泡原理)
今天给大家分享一种用JS写的导航栏,虽然我们工作中不会使用JS来做导航栏,为了练习我们用JS来做一个JS导航栏 这种方法要比其他方法代码量少很多,但是需要对事件冒泡有一定的理解,如果需要理解冒泡可以参 ...
- Flutter - 创建底部导航栏
之前写过的一篇文章介绍了 Flutter - 创建横跨所有页面的侧滑菜单, 这次就一起来学习一下底部导航栏. 底部导航栏在ios平台上非常常见,app store就是这样的风格.还有就是大家最常用的微 ...
- CSS04--对齐、 布局、导航栏
我们接着上一章,继续学习一些有关对齐.布局.导航栏的内容. 1.水平块对齐: 1.1 margin:把左和右外边距设置为 auto,规定的是均等地分配可用的外边距.结果就是居中的元素 .c ...
随机推荐
- PTA点赞狂魔
点赞狂魔 (25 分) 微博上有个“点赞”功能,你可以为你喜欢的博文点个赞表示支持.每篇博文都有一些刻画其特性的标签,而你点赞的博文的类型,也间接刻画了你的特性.然而有这么一种人,他们会通过给自己看 ...
- C++中map的介绍用法以及Gym题目:Two Sequences
Map是STL的一个关联容器,它提供一对一(其中第一个可以称为关键字(key),每个关键字只能在map中出现一次,第二个可能称为该关键字的值(value))的数据 处理能力,由于这个特性,它完成有可能 ...
- python中os.path.abspath与os.path.realpath 区别
python中os.path.abspath与os.path.realpath 区别cd /homemkdir amkdir btouch a/1.txtln -s /home/a/1.txt /ho ...
- C:clock() 计算代码执行时间
clock():捕捉从程序开始运行到clock()被调用时所耗费的事件. 这个时间的单位是 clock tick,即时钟打点 常数 CLK_TCK:机器时钟每秒走的时钟打点数 要使用这个函数需要包含头 ...
- springMVC的跳转
服务器内部跳转: return "forward:/forward/test1"; 或者 request.getRequestDispatcher(path).forward(r ...
- 解决Vue 使用vue-router切换页面时 页面显示没有在顶部的问题
有时候我们需要页面滚动条滚动到某一固定的位置,一般使用Window scrollTo() 方法. 语法就是:scrollTo(xpos,ypos) xpos:必需.要在窗口文档显示区左上角显示的文档的 ...
- Deepin-linux下的linux的终端下软件安装和卸载方法
1.方法一: sudo apt update #最好第一步是它 sudo apt install <package_name> --no-upgrade #安装该package但是不升级. ...
- BGP前缀过滤(正则表达式)
BGP的正则表达式一般用在as-path中,常用的如下: .(点):表示匹配任意一个字符,包括空格. *:表示匹配零个或多个模式的出现.即前一个字符出现0次或多次. +:表示匹配一个或多个模式的出现. ...
- 一、FreeMarker实现对js和css压缩
1.代码压缩理解:实际上就是将原有的文本中无用的注释.空行.空格去掉来压缩文件的大小.进行js和css压缩会带来如下好处:1)减小了文件的体积,减少文件占用的内存;2)减小了网络传输量和带宽占用; 3 ...
- 误删/boot下文件或目录的修复方式!
步骤:进入硬盘的急救模式,进入磁盘,挂载光盘到/media上,rpm安装内核到media目录下,从装grub程序到/dev/sda,然后将grub文件从定向到/boot下,然后重启. 第一步:进入bi ...