记录状态栏和导航栏的设置和控制,统一在基类视图控制器中完成。

状态栏。

状态栏高度为20,iOS7以后背景完全透明。

样式枚举如下:

typedef NS_ENUM(NSInteger, UIStatusBarStyle) {

UIStatusBarStyleDefault                                     = 0, // Dark content, for use on light backgrounds

UIStatusBarStyleLightContent     NS_ENUM_AVAILABLE_IOS(7_0) = 1, // Light content, for use on dark backgrounds

UIStatusBarStyleBlackTranslucent NS_ENUM_DEPRECATED_IOS(2_0, 7_0, "Use UIStatusBarStyleLightContent") = 1,

UIStatusBarStyleBlackOpaque      NS_ENUM_DEPRECATED_IOS(2_0, 7_0, "Use UIStatusBarStyleLightContent") = 2,

} ;

动画枚举如下:

typedef NS_ENUM(NSInteger, UIStatusBarAnimation) {

UIStatusBarAnimationNone,

UIStatusBarAnimationFade,

UIStatusBarAnimationSlide,

} ;

旧的常用设置方式:

[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationFade];

[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault];

但是iOS9以后废弃了这些方法。就算是在iOS7上,如果启用了基于UIViewController的状态栏控制系统,上述方法也将失效。

UIApplication.h中的注释内容为:Setting the statusBarStyle/statusBarHidden does nothing if your application is using the default UIViewController-based status bar system.

iOS7以后默认开启了UIViewController的状态栏控制系统。如果需要关闭,并采用旧的设置方式,可以将Info.plist中键值View controller-based status bar appearance设置为NO。

新的设置方式:

- (UIStatusBarStyle)preferredStatusBarStyle; // Defaults to UIStatusBarStyleDefault

- (BOOL)prefersStatusBarHidden; // Defaults to NO

- (UIStatusBarAnimation)preferredStatusBarUpdateAnimation; // Defaults to UIStatusBarAnimationFade

// This should be called whenever the return values for the view controller's status bar attributes have changed. If it is called from within an animation block, the changes will be animated along with the rest of the animation block.

- (void)setNeedsStatusBarAppearanceUpdate;

上述方法,均为UIViewController的实例方法,前三个方法可以在子类中被重写,最后主动调用setNeedsStatusBarAppearanceUpdate才会生效。

为了便于切换控制方式,提供宏控制方案:

1.在Info.plist文件中增加键值View controller-based status bar appearance = NO

2.在基类控制器的头文件中定义如下宏,便于子类检查是否启用该宏定义

//使用基于视图控制器的状态栏控制系统,UIApplication的setStatusBarHidden类似方法将无效

//开启此宏定义,请将Info.plist中View controller-based status bar appearance设置为YES,否则置为NO

#define UseDefaultUIViewControllerBasedStatusBarSystem

3.提供相关属性以设置状态栏,提供相关方法更新状态栏,并在实现文件中增加条件判断宏

#ifdef UseDefaultUIViewControllerBasedStatusBarSystem

- (UIStatusBarStyle)preferredStatusBarStyle
{
return self.statusBarStyle;
} - (BOOL)prefersStatusBarHidden
{
return self.willHideStatusBar;
} - (UIStatusBarAnimation)preferredStatusBarUpdateAnimation
{
return UIStatusBarAnimationFade;
} #endif - (void)updateStatusBar
{
#ifdef UseDefaultUIViewControllerBasedStatusBarSystem
[self setNeedsStatusBarAppearanceUpdate];
#else
[[UIApplication sharedApplication] setStatusBarHidden:self.willHideStatusBar withAnimation:UIStatusBarAnimationFade];
[[UIApplication sharedApplication] setStatusBarStyle:self.statusBarStyle];
#endif
}

导航栏

导航栏高44,iOS7以后默认透明,由UINavigationBar的translucent属性决定。

1.设置导航栏显示属性,更多是在设置UINavigationController的UINavigationBar属性。UIViewController中也存在UINavigationController类型的属性,参考如下:

[self.navigationController.navigationBar setBarStyle:UIBarStyleDefault];
[self.navigationController.navigationBar setTranslucent:YES];
[self.navigationController.navigationBar setBackgroundImage:[ImageHelper getImageWithColor:NaviBarColor] forBarMetrics:UIBarMetricsDefault];
[self.navigationController.navigationBar setShadowImage:[ImageHelper getImageWithColor:NaviBarShadowColor]];
[self.navigationController.navigationBar setTitleTextAttributes:NaviBarTitleAttributes];

2.设置标题、按钮相关属性,关注UIViewController的UINavigationItem属性

3.隐藏导航栏,可以设置navigationBarHidden属性,但建议使用方法

- (void)setNavigationBarHidden:(BOOL)hidden animated:(BOOL)animated; // Hide or show the navigation bar. If animated, it will transition vertically using UINavigationControllerHideShowBarDuration.

如果上一个界面显示导航栏,下一个界面隐藏导航栏(带有返回上一个界面的功能方法),界面切换可能出现导航栏过渡效果不佳的情况。在viewWillAppear方法中,使用代码

[self.navigationController setNavigationBarHidden:self.willHideNavigationBar animated:animated];

可以得到较好的切换效果。

4.如果带有bottomBar,当新的UIViewController将要被push到导航栈top前,可以使用UIViewController的hidesBottomBarWhenPushed控制bottomBar显示

5.合理使用导航栏控制的属性viewControllers和方法:

- (void)setViewControllers:(NSArray<UIViewController *> *)viewControllers animated:(BOOL)animated NS_AVAILABLE_IOS(3_0); // If animated is YES, then simulate a push or pop depending on whether the new top view controller was previously in the stack.

可以实现导航栈中的视图控制器切换、替换、新增、移除等功能效果。

6.导航控制的如下代理方法,可以实现切换动画的自定义,后续记录一个实现返回手势控制的分类将涉及到

- (nullable id <UIViewControllerInteractiveTransitioning>)navigationController:(UINavigationController *)navigationController

interactionControllerForAnimationController:(id <UIViewControllerAnimatedTransitioning>) animationController NS_AVAILABLE_IOS(7_0);

- (nullable id <UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController

animationControllerForOperation:(UINavigationControllerOperation)operation

fromViewController:(UIViewController *)fromVC

toViewController:(UIViewController *)toVC  NS_AVAILABLE_IOS(7_0);

UIViewController的self.view布局问题

单独一个视图控制器的self.view应该是充满容器的,origin为(0, 0),增加导航栏以后,如果不设置,仍然为(0, 0),将增加subview布局的麻烦。所以,需要关注如下属性:

@property(nonatomic,assign) UIRectEdge edgesForExtendedLayout NS_AVAILABLE_IOS(7_0); // Defaults to UIRectEdgeAll

@property(nonatomic,assign) BOOL extendedLayoutIncludesOpaqueBars NS_AVAILABLE_IOS(7_0); // Defaults to NO, but bars are translucent by default on 7_0.

extendedLayoutIncludesOpaqueBars属性,该属性表示是否包括不透明bars,默认不包括,但是iOS7以后,状态栏和导航栏都是默认透明的,所以self.view默认与屏幕边缘贴合。

edgesForExtendedLayout决定了self.view与边缘的距离,默认贴合边框,当增加导航栏以后,需要设置为UIRectEdgeNone,使self.view上边缘与导航栏下边缘贴合。

下图为self.edgesForExtendedLayout = UIRectEdgeNone;

说明:导航栏下的红条origin为(0, 0)且高20,黑条高44,蓝条高44。

下图为self.edgesForExtendedLayout = UIRectEdgeAll;

无导航栏时候,两种设置,红条都靠着顶部。

UIViewController的automaticallyAdjustsScrollViewInsets属性。

该属性自动设置self.view上scrollView类型的subview的insets,默认为YES。

当导航栏隐藏时候,该属性会导致scrollView的contentView的offsetY自动为20,也就是看到scrollView内容从状态栏下边缘开始显示,这也将带来很多麻烦。

所以导航栏隐藏时候设置self.automaticallyAdjustsScrollViewInsets = !willHideNavigationBar;可以避免意外的显示异常。

下一篇记录一个实现返回手势的分类。

base项目已更新:git@github.com:ALongWay/base.git

App开发流程之状态栏和导航栏的更多相关文章

  1. Android 4.4 沉浸式透明状态栏与导航栏

    Android 系统自4.2 開始 UI 上就没多大改变,4.4 也仅仅是添加了透明状态栏与导航栏的功能,如图 那么如今我就来给大家解说下怎样使用这个新特性,让你的 app 尾随潮流,当然假设你不在乎 ...

  2. 兼容 Android 4.4 透明状态栏与导航栏

    http://www.apkbus.com/Android-163388-1-1.html?_dsign=73d41229 android 系统自4.2 开始 UI 上就没多大改变,4.4 也只是增加 ...

  3. iOS获取状态栏和导航栏尺寸(宽度和高度)

    iPhone开发当中,有时需要获取状态栏和导航栏高度.宽度信息,方便布局其他控件.下面介绍一下如何获取这些信息: // 状态栏(statusbar) CGRect rectStatus = [[UIA ...

  4. iOS - 获取状态栏和导航栏尺寸(宽度和高度)

    iPhone开发当中,有时需要获取状态栏和导航栏高度.宽度信息,方便布局其他控件.下面介绍一下如何获取这些信息: // 状态栏(statusbar) CGRect rectStatus = [[UIA ...

  5. Android 5.0状态栏和导航栏

    Material Design推出之后,app中也開始沿用这样的风格 今天来说一下状态栏颜色设置,在4.4的时候推出了透明状态栏和导航栏.在不使用第三方库的情况下,4.4还是没有全然解决存在actio ...

  6. 【转】iPhone获取状态栏和导航栏尺寸(宽度和高度)

    原文网址:http://blog.csdn.net/chadeltu/article/details/42708605 iPhone开发当中,有时需要获取状态栏和导航栏高度.宽度信息,方便布局其他控件 ...

  7. Android隐藏状态栏、导航栏

    Android隐藏状态栏.导航栏 private void hideStatusNavigationBar(){ if(Build.VERSION.SDK_INT<16){ this.getWi ...

  8. iOS 状态栏、导航栏、工具栏、选项卡大小

    1.状态栏状态栏一般高度为20像素,在打手机或者显示消息时会放大到40像素高,注意,两倍高度的状态栏在好像只能在纵向的模式下使用.如下图用户可以隐藏状态栏,也可以将状态栏设置为灰色,黑色或者半透明的黑 ...

  9. 20个可以帮你简化iOS app开发流程的工具

    这里推荐20个可以帮你简化iOS app开发流程的工具.很多开发者都使用过这些工具,涉及原型和设计.编程.测试以及最后的营销,基本上涵盖了整个开发过程. 原型和设计 有了一个很好的创意后,你要做的不是 ...

随机推荐

  1. Struts2知多少(2) Struts2 是什么

    Struts2是流行和成熟的基于MVC设计模式的Web应用程序框架. Struts2不只是Struts1下一个版本,它是一个完全重写的Struts架构. WebWork框架开始以Struts框架为基础 ...

  2. MyBatis知多少(7)持久层

    持久层是适合使用MyBatis的地方.在面向对象的系统中,持久层主要关注对象(或者更精确地说应该是存储在那些对象中的数据)的存取.在企业应用程序中持久层通常用关系数据库系统来存储数据,虽然某些情况下其 ...

  3. rsync安装配置及故障解决完全教程[window, 文件同步]

    Rsync是的全称是: remote synchronize, 也就是远程同步数据, 它是一款不错的文件同步软件,而且是免费的, 它在镜像保存整个目录树和文件系统的同时保持原来文件的权限.时间.软硬链 ...

  4. 免费下载:320+ 手绘风格 Apple iOS7 图标

    Themify 图标是一套用在网页设计和应用程序的图标,包括 320+ 手工制作的像素完美的苹果  iOS7 图标中汲取灵感.这些图标完全免费,您可以用于任何目的,无论是个人或商业. 您可能感兴趣的相 ...

  5. linux根目录下文件夹概览

    / 根目录 /bin 存放必要的命令 /boot 存放内核以及启动所需的文件等 /dev 存放设备文件 /etc 存放系统的配置文件 /home 用户文件的主目录,用户数据存放在其主目录中 /lib ...

  6. Spring应用教程-1

    作者:禅楼望月(http://www.cnblogs.com/yaoyinglong) Spring是Web框架,是容器框架,用于配置bean,并维护bean之间的关系的框架. 1. Spring在整 ...

  7. [Logstash]使用详解

    Logstash是一款轻量级的日志搜集处理框架,可以方便的把分散的.多样化的日志搜集起来,并进行自定义的处理,然后传输到指定的位置,比如某个服务器或者文件. 本文针对官方文档进行翻译以及实践,希望有更 ...

  8. 如何根据iframe内嵌页面调整iframe高宽续篇

    接着昨天的工作 如何根据iframe内嵌页面调整iframe高宽 来说,按照文章中说的第二种方法实现代码如下: 实现 A.com/detail/view 页面的iframe代码如下: <ifra ...

  9. 通过Nginx实现负载均衡

    百度了下负载均衡:英文名称为Load Balance,其意思就是分摊到多个操作单元上进行执行,例如Web服务器.FTP服务器.企业关键应用服务器和其它关键任务服务器等,从而共同完成工作任务 嗯,跟我理 ...

  10. Winform开发框架之通用高级查询模块

    最近一直忙于公司的事情,虽然一直在做一些相关的技术研究,但是很久没能静下心来好好写写博客文章了,想想也有半个月之多了,这半个月来,也一直致力于改善我的WInform开发框架,使得自己及客户使用起来更加 ...