原文地址: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. my97中文乱码问题

    在使用my97日期插件后页面显示中文乱码问题: 解决方法: 把下面这段代码复盖到你的ZH-CN.js就解决了 var $lang={ errAlertMsg: "\u4E0D\u5408\u ...

  2. 使用angular.bootstrap() 完成模块的手动加载

    之前我们看到使用ng-app指令,可以实现模块的自动加载.现在我们看下,angular中如何手动加载模块.需要使用到angular.bootstrap这个函数. <html> <he ...

  3. getComputedStyle/currentStyle/style之间的爱恨情仇

    getComputedStyle是? getComputedStyle是一个可以获取当前元素所有最终使用的CSS属性值.返回的是一个CSS样式声明对象([object CSSStyleDeclarat ...

  4. [转]python 常用类库!

    Python学习 On this page... (hide) 1. 基本安装 2. Python文档 2.1 推荐资源站点 2.2 其他参考资料 2.3 代码示例 3. 常用工具 3.1 Pytho ...

  5. php关于ob_start('ob_gzhandler')启用GZIP压缩的bug

    如果使用ob_start("ob_gzhandler"); 则ob_clean()后面的输出将不显示,这是个bug,可以用ob_end_clean();ob_start(" ...

  6. .NET MVC Filter异常处理

    MVC程序中自带的HandleErrorAttribute,来处理异常,不在显示黄页.前提是在web.config 中 system.web中关闭customerError选项. 但是很多情况下调试异 ...

  7. ORA-00600: internal error code, arguments: [SKGMFAIL], [2], [4], [4], [1], [], [], [], [], [], [], [

    ORA-00600: internal error code, arguments: [SKGMFAIL], [2], [4], [4], [1], [], [], [], [], [], [], [ ...

  8. vuex 使用笔记

    1. 在store.js中 储存数据状态 02. 在action.js中分发行为 03. 在页面中获取并使用状态

  9. Android selecter背景选择器使用

    android:drawable这个属性是必须的,默认时的背景图片. android:state_pressed布尔值.true指当用户点击或者触摸该控件的状态.默认为false android:st ...

  10. CentOS 安装Paramiko模块

    转自:http://www.cnblogs.com/hyli/p/3910585.html 1.下载安装包: https://pypi.python.org/packages/source/p/par ...