#UINavigationController补充
- 问题1 在同一个导航栏下面,A->pushB->pushC,C->popB->popA, 其中AC均有导航栏,但是B没有.导航栏怎么优雅的隐藏.
- 问题2 自定义返回按钮,系统滑动返回手势依然有效
- 问题3 状态栏的隐藏
下面听我娓娓道来.
对于问题1的解答
问题一的由来是:在开发中,遇到播放器的页面,竖屏时,一般导航栏隐藏.
首先,我想到的是,关于导航栏的显示隐藏的处理要在B视图中做处理,这样对其他的页面的影响最小,也有利于以后的扩展,比如可能有更多的页面push指向B,或者pop指向B.
尝试的过程:
起初
在viewDidLoad函数里面
|
|
在viewWillDisappear函数里面
|
|
这样无论是 B->pushC,还是B->popA,AC两个页面的导航栏均正常显示,但是C->popB时发现B的导航栏没有隐藏掉.观察代码发现,B中导航栏的隐藏的方法只写在了viewDidLoad里面了,在C->popB时,B页面viewDidLoad的函数是不再执行,只有viewWillAppear,viewDidAppear等执行.
所以我把代码放在了viewWillAppear里面
|
|
到了这里,导航栏貌似都显示正常,但是真机测试发现,当C->popB时,在滑动返回的过程中,导航栏立刻就隐藏掉了,即B页面的viewWillAppear立刻就执行,这就导致C->popB时的动画效果很丑,那我想是否把隐藏导航栏的方法放在 viewDidAppear里面,即
|
|
,但是此时发现该方法执行了,但是隐藏导航栏的效果却没有,显然当页面已经完成绘制后,此方法无效.然后我想到了带有动画效果的隐藏导航栏的方法,如下
|
|
然后运行发现,带有一个向上隐藏导航栏的动画效果.
且在多次测试中发现,显示导航栏的代码
|
|
此方法偶尔会无效,即从B->pushC,或者B->popA时,偶尔导航栏没有正常显示.
所以最终决定在viewWillDisappear函数里面,隐藏导航栏的方法改为
|
|
小结一:关于此题的解决办法时,在viewdidload函数里面,写入self.navigationController?.navigationBar.alpha = 1.0因为显然初始化的时候不希望其有动画效果.然后加上下面的代码即可完美解决此问题.
|
|
引申,ios中很多属性的赋值,有2种,一种是直接赋值,一种是通过set方法.2种方法的区别就是有无动画.比如scrollview设置其偏移量.前后两种达到的效果是一样的.但是前者会导致一个Bug,即scrollViewDidScroll会根据偏移量的个数走几次.所以最终采用uiview动画和直接赋值结合.
代码如下:
|
|
对于问题2的回答
之前在iOS-UINavigationController官方文档分析大总结
中我写到若是想要使用系统的滑动返回,最好不要自定义,我觉得有必要更正一下.
在项目开发中,你会发现一般导航栏的背景色,返回按钮 都需要自定义处理.
在项目基类导航视图控制器里面,代码如下即可.
|
|
在基类视图控制器里面,代码如下
|
|
默认是显示自定义的返回按钮,在不需要显示返回按钮的时候比如首页,则直接showBack = false 即可.
当需要自定义返回按钮,则调用initLeftBarItem(_ name:String?,imageName:String?,leftAction:@escaping WMButtonClickBlock)即可.
包括自定义导航栏右按钮皆可以在基类里面定义好,然后在子类里面直接调用即可.
对于问题3的回答
项目中涉及到播放器的全屏与竖屏之间切换,经过调研以及研究市场主流的播放器的横竖屏切换发现,横竖屏切换最好的解决办法是旋转播放器,然后更新播放器的约束,这个时候发现状态栏还是竖屏的状态,显然需要隐藏掉.
解决办法为:
创建变量标志是否全屏,在需要全屏的时候,该标志位置为true,同时在
在info.plist中View controller-based status bar appearance 设置为NO
|
|
若在这个页pop到其他页面时发现状态栏消失,需要在返回的方法里面主动将该标志位置为true.