• iOS 导航栏的那些事儿


    饮水思源:http://ios.jobbole.com/90851/

    最近项目里有个需求和导航栏的样式定制有关,深入之后发现之前理解的一些概念有些模糊,刚好趁着这次机会全面整理了一下。

    从 iOS7 开始,苹果采用了大量的扁平化和毛玻璃风格,刚升级到 iOS7 之后会发现界面的布局多多少少有一些偏差(当然现在新建的项目没有这方面困扰,不需要经历6到7的适配),适配过程中会发现如下一些属性,

    根据字面意思看上去这些属性很好理解,但是发现他们组合之后会有一些不同的表现,一些奇怪的问题也不知道什么原因导致的。不用担心,接下去我会全面的解析一下这几个属性的含义,保证你再也不怕各种奇怪的导航栏问题啦。

    edgesForExtendedLayout + translucent

    iOS7 以后,edgesForExtendedLayout 的默认设置是 UIRectEdgeAll,translucent 的默认值是 true。这种组合会使 rootView 的布局从(0,0)开始,即 view 的内容会被导航栏遮挡住,大多数情况下将 edgesForExtendedLayout 修改为 UIRectEdgeNone 就能解决布局被遮挡的问题。将 translucent 设置成 false 也会使 rootView 从导航栏底部开始,但是 translucent = false 时即使将 edgesForExtendedLayout 再改成 UIRectEdgeAll rootView 还是从导航栏底部开始布局。如何可以在导航栏不透明的情况下让 rootView 从(0,0)开始布局呢?苹果也考虑到了这种需求,提供了 extendedLayoutIncludesOpaqueBars 这个属性。

    小结:translucent 为 true,rootView 从(0,0)开始布局,修改 edgesForExtendedLayout 属性可以改变布局;translucent 为 false,rootView 从导航栏底部开始布局,修改 edgesForExtendedLayout 属性无法改变布局。

    extendedLayoutIncludesOpaqueBars + translucent

    前面我们知道了 translucent 为 false 时,修改 edgesForExtendedLayout 也无法使 rootView 从(0,0)开始布局。苹果为此提供了 extendedLayoutIncludesOpaqueBars,字面上理解的意思就是在不透明的导航栏下也全屏显示。

    这里多提一点,在 ViewController 的生命周期中有 viewDidLoad,viewWillAppear,viewDidAppear,viewWillDisappear,viewDidDisappear,上述提到的这些属性需要在 viewDidAppear 之前设置好,viewDidAppear 可以认为系统已经根据配置布局好了,在这里展示给用户看。

    automaticallyAdjustsScrollViewInsets

    automaticallyAdjustsScrollViewInsets 默认值是 true,表示在全屏模式下会自动修改第一个添加到 rootView 的 scrollview 的 contentInset 为(64,0,0,0),这样 scrollview 就不会被导航栏遮挡了。

    关于 scrollview 有一个问题比较常见,这里解析一下原因。我们经常会这么使用一个 tableView,

    这样在默认情况下(translucent = true, edgesForExtendedLayout = UIRectEdgeAll),tableView的显示没有问题。但是当我们将 edgesForExtendedLayout 设置成 UIRectEdgeNone 时,当 tableView 的内容比较多时底部的内容反而显示不下。这就很奇怪了,按照前面的结论,这时候 tableView是从导航栏底部开始布局的,contentInset 也是(0,0,0,0),怎么底部的内容会被遮挡一部分呢?原因在于 self.tableView = [[UITableView alloc] initWithFrame:self.view.bounds]; 初始化时 rootView 的 frame 还是(0,0,screenWidth,screenHeight),只需要在 viewWillLayoutSubviews 中重新修改一下 tableview 的 frame 即可,

    UINavigationBar 修改背景色

    UINavigationBar 是 UIView 的子类,首先想到的是修改背景色,
    self.navigationController.navigationBar.backgroundColor = [UIColor greenColor];

    11128529-1f438c79ac15bd49

    发现这并不是我们想要的效果,为什么绿色变淡了呢?通过 Xcode 的 ViewDebugging 我们可以看到 UINavigationBar 内部还有一些子视图,这些子视图的背景色会遮挡住我们设置的颜色。

    12128529-28d5b3ada81b32fe

    查看 UINavigationBar 的接口我们发现 setBackgroundImage,设置

    结果如下

    13128529-e5d09241f2e856a5
     

    小结:设置 UINavigationBar 的 backgroundImage 可以修改导航栏的背景色。

    translucent 和 setBackgroundImage

    前面提到我们可以通过修改背景图片来修改导航栏的背景色,设置了背景图片后在有些页面我们会遇到一些奇怪的问题,发现原来布局正常的页面显示不对了,会多出一部分空白或者被导航栏遮挡住了。

    通过打印出 translucent 的值我们发现设置了纯色的背景图后原来半透明的导航栏变成了不透明的,结合前面提到的 translucent 对布局起点的影响,如果页面是按照半透明情况,即 rootView 从(0,0)开始布局来设置子视图的 frame,那么设置了纯色背景图后 translucent 变成了 false,即 rootView 从(0,64)开始布局。为什么设置背景图片会影响 translucent 呢,通过查看文档发现了如下说明,

    也就是说背景图片如果包含 alpha 的色值,系统会默认将 translucent 设置为 true,没有包含 alpha 色值会将 translucent 设置为 false。这下真相大白了,原来我们前面设置了纯绿色的背景图片,是不包含 alpha 色值的,即系统默认将 translucent 设置成了 false。但这是针对没有手动设置 translucent 值的情况,如果我们手动设置了 translucent,那么系统就不会根据背景图片的 alpha 来修改 translucent

    至此,我们了解了苹果是如何使用这几个属性的,针对 iOS7 以上,这里做一下总结:

      1. iOS7 以后 translucent 默认为 true,rootView 从(0,0)开始布局,修改 edgesForExtendedLayout 属性可以改变布局;
      2. translucent 为 false,rootView 从导航栏底部开始布局,修改 edgesForExtendedLayout 属性无法改变布局,可以通过设置 extendedLayoutIncludesOpaqueBars 从(0,0)开始布局;
      3. automaticallyAdjustsScrollViewInsets 默认值是 true,表示在全屏模式下会自动修改第一个添加到 rootView 的 scrollview 的 contentInset 为(64,0,0,0),用来纠正scrollview在全屏模式下的显示;
      4. 设置 UINavigationBar 的背景图片可以改变导航栏背景色,如果背景图片包含 alpha 的色值,系统会默认将 translucent 设置为 true,没有包含 alpha 色值会将 translucent 设置为 false。但这是针对没有手动设置 translucent 值的情况,如果我们手动设置了 translucent,那么系统就不会根据背景图片的 alpha 来修改 translucent
  • 相关阅读:
    C# winform 获取标题栏,状态栏,菜单栏的高度
    <转载>OleDb操作Access数据库:新增记录时获取自动编号的主键值
    《名利场》:微软 “ 失落的十年”
    Lisp的永恒之道(转)
    Google Earth KML数据格式转换成Shp数据格式(转)
    【转】ArcGIS投影转换与坐标转换
    利用Mono.Cecil动态修改程序集来破解商业组件(仅用于研究学习)
    C# mouseDoubleClick与DoubleClick的关系
    ACCESS通用操作数据类
    VS2010单元测试入门实践教程
  • 原文地址:https://www.cnblogs.com/howdoudo/p/6137864.html
Copyright © 2020-2023  润新知