导航栏协议方法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 ...
随机推荐
- static静态变量使用@Value注入方式
@Componentpublic class MyConfig { private static String env; public static String getEnv() { return ...
- AliWareMQ
mq配置文件(Spring) 主要是顺序消息的配置,以及多实例的配置(需要在控制台配置p/c) <?xml version="1.0" encoding="UTF- ...
- P1567
最大子数组和问题,dp或者分治.. #include <bits/stdc++.h> #define rep(i, a, b) for(int i = a; i <= b; i++) ...
- idea抽取方法
问题:有时候一个方法里面嵌套了很多逻辑,想拆分为多个方法方便调用:或者一个方法复用性很高,这时,这个方法嵌套在局部方法里面肯定是不方便的,如何快速抽取出这个方法? public class Demo ...
- cmd添加管理员账号
net user 用户名 密码 /add net localgroup Administrators 用户名 /add
- redis基本操作,基于StringRedisTemplate,存储,取值,设置超时时间,获取超时时间,插入list操作
@Autowired private StringRedisTemplate stringRedisTemplate; @GetMapping("/test") void test ...
- RFID学习
RFID:射频识别卡有读卡器和电子标签(有源/无源/半有源)组成,工作频率有LF/HF/UHF/MF,低频的通讯距离近(1m)常用来做门禁:高频的通讯距离远可以批量读取. 无源的轻巧/防拆一致性好,在 ...
- 「SDOI2005」区间
「SDOI2005」区间 传送门 记录每一个位置作为左端点和右端点的出现次数,然后直接考虑差分即可. 参考代码: #include <cstdio> #define rg register ...
- idea取消参数标记
- 【协作式原创】查漏补缺之Go并发问题(单核多核)
主要回答一下几个问题 1.单核并发问题 2.多核并发问题 2.几个不正确的同步案例 1.单核并发问题 先看一段go(1.11)代码: 单核CPU,1万个携程,每个携程执行100次+1操作, 思考n最终 ...