原文地址:http://www.jianshu.com/p/930643270455

总所周知,苹果从iOS7开始采用扁平化的界面风格,颠覆了果粉们“迷恋”的拟物化风格。对于开发者而言,全新的风格带来新的接口,这些新的接口改动中,有些更加合理了,有些更加方便了,而有些可能让开发者容易迷糊,下面本人就来谈谈iOS7这些新添加“鬼魅”的接口中的经常接触到的一个----UITabBar/UINavigationBar的translucent属性。

新的属性translucent简介

顾名思义,translucent属性能决定UITabBar/UINavigationBar是否为半透明的效果,苹果官方对此的解释如下:

  • UINavigationBar的translucent属性解释

    /*
    New behavior on iOS 7.
    Default is YES.
    You may force an opaque background by setting the property to NO.
    If the navigation bar has a custom background image, the default is inferred
    from the alpha values of the image—YES if it has any pixel with alpha < 1.0
    If you send setTranslucent:YES to a bar with an opaque custom background image
    it will apply a system opacity less than 1.0 to the image.
    If you send setTranslucent:NO to a bar with a translucent custom background image
    it will provide an opaque background for the image using the bar's barTintColor if defined, or black
    for UIBarStyleBlack or white for UIBarStyleDefault if barTintColor is nil.
    */
    @property(nonatomic,assign,getter=isTranslucent) BOOL translucent NS_AVAILABLE_IOS(3_0) UI_APPEARANCE_SELECTOR;
    // Default is NO on iOS 6 and earlier. Always YES if barStyle is set to UIBarStyleBlackTranslucent
  • UITabBar的translucent属性解释

    /*
    Default is YES.
    You may force an opaque background by setting the property to NO.
    If the tab bar has a custom background image, the default is inferred from the alpha
    values of the image—YES if it has any pixel with alpha < 1.0
    If you send setTranslucent:YES to a tab bar with an opaque custom background image
    the tab bar will apply a system opacity less than 1.0 to the image.
    If you send setTranslucent:NO to a tab bar with a translucent custom background image
    the tab bar will provide an opaque background for the image using the bar's barTintColor if defined, or black
    for UIBarStyleBlack or white for UIBarStyleDefault if barTintColor is nil.
    */
    @property(nonatomic,getter=isTranslucent) BOOL translucent NS_AVAILABLE_IOS(7_0);

    简而言之,这个BOOL属性能控制UITabBar/UINavigationBar的半透明效果,默认为YES,即默认情况下为半透明效果(后面会详细解释这两段官方文字描述的含义)。

translucent缘何“鬼魅”

新属性的出现往往会导致一些“注意事项”,主要体现为被半透明效果处理后产生的色差和添加的类view控件的坐标变动。

默认情况下,如果使用UITabBarController和UINavigationBarController(translucent属性默认为YES),设置一个蓝色的view添加其中并设置距离屏幕边距为(0,0,0,0),展示效果如下:

可以看到,UITabBarController和UINavigationBarController被蓝色的view“穿透”了,此时view的边距也正如设置的一样,零点坐标在(0,0)处。

这时候,如果将view替换成tableView,展示效果如下:

可以看到,tableView的cell并没有因为“穿透”效果而出现被遮挡的情况,这是由于苹果对滚动视图的特殊性进行处理:对于类ScrollView,系统默认默认控制器属性automaticallyAdjustsScrollViewInsets默认为YES。

  • automaticallyAdjustsScrollViewInsets = YES时系统底层所干的事
    scrollView的内容原本没有内边距,但是考虑到导航栏(高度44px)、状态栏(高度20px)、TabBar(高度49px)会挡住后面scrollView所展示的内容,系统自动为scrollView增加上下的内边距,这时候我们打印一下tableView的描述(友情提示:tableView继承自scrollView):

    tableView描述.png

    可以看出,contentOffset(内容坐标偏移量)和contentSize(内容尺寸大小)都发生了变化,结合tableView自身的frame可以看出,系统自动为scrollView增加了顶部64px的内边距以及底部49px的内边距,正好是导航栏高度+状态栏高度以及TabBar高度。一旦手动在系统布局页面之前设置automaticallyAdjustsScrollViewInsets = NO,将会取消上述操作,届时scrollView内容将会被部分挡住
    请注意:上述的情况仅仅对UIScrollView或者子类(如UITableView)有效。

  • 非滚动视图中导致“鬼魅”的原因
    从上述内容中,我们可以了解到滚动视图默认情况下系统会给滚动内容增加上下内边距,以防内容被导航条和TabBar遮挡,但是实际上在常用的项目界面结构(TabBarController--NavigationController--ViewController)以及系统默认情况下,viewController中的view是没有内边距的(也就是说view穿透上下两个Bar)。但是我们有时候会看到应用中会有这样的情形:非滚动视图依然有类似增加上下内边距的效果,自己并没有手动更改过视图的frame。这种情况,就要结合其他几个系统的属性来解释了。

针对非滚动视图的需求

由上述内容我们知道,默认情况下,导航条和TabBar都是半透明,添加在上面的控制器的视图会有“穿透”效果。如果现在有这样的需求:对于非滚动视图,从原点(0,0)布局,但是内容不被遮挡,能够正常显示。
这时候我们需要区分两种情况:是否需要导航条/TabBar带有半透明效果。

  • 保留半透明效果(导航条/TabBar的translucent == YES)

    1. 手动修改frame布局,从(0,64)开始布局,底部同理,需要计算坐标尺寸,比较繁琐。
    2. 修改viewController的edgesForExtendedLayout属性,edgesForExtendedLayout = UIRectEdgeNone
      (备注:设置后,控制器的view的frame的坐标Y增加64px紧挨着navigationBar下方,底部同理,该属性支持iOS7及以后的版本。)
      注意:这里虽然看着导航条和TabBar还有半透明效果,但是实际上下面的内容已经无法再”穿透“了。
      运行效果如下图所示:

  • 不保留半透明效果(导航条/TabBar的translucent == NO)
    将TabBar和导航条的translucent属性分别设置为NO,不做任何其他修改,此时bar的背景颜色为默认的白色,且不再有色差,运行效果如下图所示:

    导航条的translucent设置为NO效果展示

    TabBar的translucent设置为NO效果展示

关于iOS7之后与view全屏相关的知识点

在iOS7之后,默认情况下,控制器的view是”全屏“的,也就是说,即便有TabBar或者NavigationBar,控制器的view也是可以”穿透至全屏“的,针对这一特性,苹果对UIViewController提供了以下几个属性供开发者使用:

// 在iOS7之前,控制器的view默认非全屏,如果想要全屏效果,需要设置为YES,该属性已从iOS7开始过期
@property(nonatomic,assign) BOOL wantsFullScreenLayout NS_DEPRECATED_IOS(3_0, 7_0) __TVOS_PROHIBITED;
// Deprecated in 7_0, Replaced by the following: 该属性被以下三个属性代替 // Defaults to UIRectEdgeAll
@property(nonatomic,assign) UIRectEdge edgesForExtendedLayout NS_AVAILABLE_IOS(7_0); // Defaults to NO, but bars are translucent by default on 7_0.
@property(nonatomic,assign) BOOL extendedLayoutIncludesOpaqueBars NS_AVAILABLE_IOS(7_0); // Defaults to YES
@property(nonatomic,assign) BOOL automaticallyAdjustsScrollViewInsets NS_AVAILABLE_IOS(7_0);

下面解释一下这三个属性:

  • edgesForExtendedLayout:意思是view的边缘允许额外布局的情况,默认为UIRectEdgeAll,意味着全屏布局(带穿透效果)。

  • extendedLayoutIncludesOpaqueBars:意思是额外布局是否包括不透明的Bar,默认为NO,意味着如果导航条或者TabBar非透明,view内容不会被他们遮挡,如果该属性设置为YES,那么在导航条或者TabBar非透明的情况下,view的内容将会被他们遮挡(原点为0,0),该属性仅仅对非透明的Bar控件有效。
    示例展示如下图所示(代码设置 navigationBar.translucent = NO 并且 extendedLayoutIncludesOpaqueBars = YES)

    非透明导航条遮挡内容效果展示
  • automaticallyAdjustsScrollViewInsets:意思是是否由系统自动调整滚动视图的内边距,默认为YES,意味着系统将会根据导航条和TabBar的情况自动增加上下内边距以防止滚动视图的内容被Bar遮挡。

设置导航条或者TabBar背景图片的注意事项

这里会详细解释官方文档对translucent属性的注释,为什么放到这里才说?因为官方文档对该属性的解释全部跟设置导航条或者TabBar的背景图片有关!说明苹果也知道,这里坑很多,下面就来梳理一下吧。。。

translucent属性的官方解释

  • UINavigationBar/UITabBar的translucent属性解释:默认为YES,可以通过设置NO来强制使用非透明背景,如果导航条使用自定义背景图片,那么默认情况该属性的值由图片的alpha(透明度)决定,如果alpha的透明度小于1.0值为YES。如果手动设置translucent为YES并且使用自定义不透明图片,那么会自动设置系统透明度(小于1.0)在这个图片上。如果手动设置translucent为NO并且使用自定义带透明度(透明度小于0)的图片,那么系统会展示这张背景图片,只不过这张图片会使用事先确定的barTintColor进行不透明处理,若barTintColor为空,则会使用UIBarStyleBlack(黑色)或者UIBarStyleDefault(白色)。

设置导航栏背景图片透明度问题

  • 如果背景图片没有透明度,系统会自动把导航控制器的栈顶控制器的view的Y值增加64,如果没有透明度,则不会增加。
  • 这一情况的图片必须是imageSet格式的,并且图片的透明度为1(不透明),系统才会去调整。

【转】iOS学习之translucent属性的更多相关文章

  1. ios学习路线—Objective-C(属性修饰符)

    readonly: 此标记说明属性是只读的,默认的标记是读写,如果你指定了只读,在@implementation中只需要一个读取器.或者如果你使用@synthesize关键字,也是有读取器方法被解析. ...

  2. 【原】iOS学习之事件处理的原理

    在iOS学习23之事件处理中,小编详细的介绍了事件处理,在这里小编叙述一下它的相关原理 1.UITouch对象 在触摸事件的处理方法中都会有一个存放着UITouch对象的集合,这个参数有什么用呢? ( ...

  3. iOS学习路线图

    一.iOS学习路线图   二.iOS学习路线图--视频篇       阶 段 学完后目标 知识点 配套学习资源(笔记+源码+PPT) 密码 基础阶段 学习周期:24天       学习后目标:    ...

  4. iOS学习之UINavigationController详解与使用(一)添加UIBarButtonItem

    http://blog.csdn.net/totogo2010/article/details/7681879 1.UINavigationController导航控制器如何使用 UINavigati ...

  5. iOS学习资源个人整理

    1208更新: http://www.tuyiyi.com                                    图翼网 https://github.com/Alamofire/Al ...

  6. 【原】iOS学习之SQLite和CoreData数据库的比较

    1. SQLite数据库 sqlite数据库操作的基本流程是, 创建数据库, 再通过定义一些字段来定义表格结构, 可以利用sql语句向表格中插入记录, 删除记录, 修改记录, 表格之间也可以建立联系. ...

  7. IOS学习笔记之关键词@dynamic

    IOS学习笔记之关键词@dynamic @dynamic这个关键词,通常是用不到的. 它与@synthesize的区别在于: 使用@synthesize编译器会确实的产生getter和setter方法 ...

  8. iOS学习笔记-精华整理

    iOS学习笔记总结整理 一.内存管理情况 1- autorelease,当用户的代码在持续运行时,自动释放池是不会被销毁的,这段时间内用户可以安全地使用自动释放的对象.当用户的代码运行告一段 落,开始 ...

  9. iOS学习笔记10-UIView动画

    上次学习了iOS学习笔记09-核心动画CoreAnimation,这次继续学习动画,上次使用的CoreAnimation很多人感觉使用起来很繁琐,有没有更加方便的动画效果实现呢?答案是有的,那就是UI ...

随机推荐

  1. 2 column数据构成主键的表转化为1 column为主键的表

    问题:假设有张学生成绩表(tb)如下:姓名 课程 分数张三 语文 74张三 数学 83张三 物理 93张三 德语 null李四 语文 74李四 数学 84李四 物理 94李四 英语 80想变成(得到如 ...

  2. java基础知识(五)java类

    类是java的核心和本质,是java语言的基础. 一.java中的类 1.类class 一个类可以包含局部变量.实例变量.类变量(静态变量) 一个类至少有一个构造方法,如果没有,系统会默认给出一个无参 ...

  3. ES6学习笔记二

    字符串遍历 var str = 'hello'; for(let s of str){console.log(s += ' ')} //h e l l o 字符串查找:添加了include(str,i ...

  4. KVM 虚拟机联网方式:NAT 和 Bridge

    KVM 客户机网络连接有两种方式: 用户网络(User Networking):让虚拟机访问主机.互联网或本地网络上的资源的简单方法,但是不能从网络或其他的客户机访问客户机,性能上也需要大的调整.NA ...

  5. C#微信公众号开发系列教程二(新手接入指南)

    http://www.cnblogs.com/zskbll/p/4093954.html 此系列前面已经更新了两篇博文了,都是微信开发的前期准备工作,现在切入正题,本篇讲解新手接入的步骤与方法,大神可 ...

  6. using 声明与编译指令

    using std::cout; // using 声明 using namespace std; // using 编译指令,导入std里面的所有名称 一般使用using 声明,它只会导入指定的名称 ...

  7. php下载远程文件方法~

    直接上代码: getFile("http://easyread.ph.126.net/N8gDl6ayo5wLgKbgT21NZQ==/7917056565549478184.jpg&quo ...

  8. POJ 2226二分图最大匹配

    匈牙利算法是由匈牙利数学家Edmonds于1965年提出,因而得名.匈牙利算法是基于Hall定理中充分性证明的思想,它是二部图匹配最常见的算法,该算法的核心就是寻找增广路径,它是一种用增广路径求二分图 ...

  9. Linux+PHP+MySql网站迁移配置

    LINUX下MYSQL数据库默认数据库文件位置: 数据库文件默认在:cd /usr/share/mysql 配置文件默认在:/etc/my.cnf ———————————– 数据库目录:/var/li ...

  10. Python使用TuShare将股票数据保存到Oracle数据

    TuShare是个获取股票数据的模块包,我们进行分析,需要将股票数据保存到本地,避免每次都从网上获取,由于本机装有ORCALE,以ORACLE为例介绍如何保存股票数据到本地. 一.大致思路:我们先获取 ...