导航栏协议方法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 ...
随机推荐
- CSS选择器效率问题
今天学习了CSS各类选择器,对其效率问题有些疑问,故总结了一些学习笔记 有很多人都忘记了,或在简单的说没有意识到,CSS在我们手中,既能很高效,也可以变得很低能.这很容易被忘记,尤其是当你意识到你会的 ...
- 蚁人cp数
可怜的蚁人进入量子领域后,黄蜂女被灭霸的一个响指带走,导致可怜的蚁人困在了量子领域,为了生存,他们开始建造自己家园. 蚁人为了方便在这里生存,他们建造了自己火车站.某车站有N个人上车,其中M对是情侣, ...
- python导入openpyxl报错问题,终于解决啦
问题:折腾了一上午,安装.卸载openpyxl多次,cmd中明明显示安装成功,可python文件import时就是报错 1.安装openpyxl后,python文件导入一直报错,经过一上午的努力,终于 ...
- workspace 打开的是我的电脑
在system tree板块的空白处右键-->set root-->current workspace 即可恢复workspace.
- 探索 Python + HyperLPR 进行车牌识别
概要 HyperLRP是一个开源的.基于深度学习高性能中文车牌识别库,由北京智云视图科技有限公司开发,支持PHP.C/C++.Python语言,Windows/Mac/Linux/Android/IO ...
- 例题3_1 TeX中的引号(TeX Quotes,UVa 272)
在TeX中,左双引号是“``”,右双引号是“''”.输入一篇包含双引号的文章,你的任务是把它转换成TeX的格式. 样例输入: "To be or not to be,"quoth ...
- 《如何写好商业计划书》---创业学习---训练营第三课---HHR---
一,<开始上课> 1,投资人不愿意约见的原因:创始人没有把项目的投资价值和亮点呈现在商业计划书里. 2,BP的三个常见的错误:不够完整,关键内容没有呈现出来:华而不实:篇幅过长. 3,预热 ...
- POJ2516 Minimum Cost
亲爱的,一个货物销售者,现在遇到了一个大问题,他需要你的帮助.在他的销售区域有 N 个店主(从 1 到 N)向他储存货物,Dearboy 有M 个供应点(从 1 到 M),每个供应点提供 K 种不同的 ...
- 创建DataTable与DataGridView进行绑定
private DataTable dt = new DataTable(); BindingSource bs = new BindingSource(); /// <summary> ...
- Uncaught SyntaxError: Unexpected identifier 报错 import Vue from 'vue';
一般情况是因为Webpack与webpack-dev-server版本不兼容导致. package.json { "name": "vue-loader-demo&quo ...