iOS开发-适配iOS 11及iPhoneX(1)

前言

iOS 11正式版将于9月19号正式推送,作为开发者当然不会等到正式版推出之后才去体验最新版的iOS 11,于是最近几天安装了下XCode9,在模拟器上跑了一下自己的App,发现了一些问题,本文主要谈一下iOS 11下tableView内容下移的问题。

一.为什么会发生内容下移

废话少说先上图

问题

1.原因分析

在iOS 11中Apple干掉了ViewController中的automaticallyAdjustsScrollViewInsets这个属性,当tableview的frame超出了安全区域后系统会自动的调整SafeAreaInsets的值,而iOS 11中真正影响tableview内容与边缘的变成了adjustedContentInset而不是以前的contentInset。由于系统对adjustedContentInset进行了调整导致了tableView的内容到边缘的距离发生了变化,下移距离分别是20pt(没有navigationBar,下移了一个statusBar的高度),64pt(navigationBar的高度以及statusBar的高度)。

2.关于安全区域

安全区域的概念是在iOS 11提出的,如图

SafeArea

简单来说下什么是安全区域,就是把View放在整个屏幕的可视部分,当有navigationbar存在时安全区域也是从navigationbar的bottom开始的,若同时存在tabBar则中间区域为安全区域,ViewController中还提供了additionalSafeAreaInsets去扩展安全区域。

safeAreaInsets属性反映了一个view距离该view的安全区域的边距。对于一个Controller的根视图而言,SafeAreaInsets值包括了被statusbar和其他可视的bars覆盖的区域和其他通过additionalSafeAreaInsets自定义的insets值。对于view层次中得其他view,SafeAreaInsets值反映了view被覆盖的部分。如果一个view全部在它父视图的安全区域内,则SafeAreaInsets值为(0,0,0,0)。

二、 adjustContentInset

在iOS11中scrollView新增的两个属性:adjustContentInset和contentInsetAdjustmentBehavior。

adjustContentInset表示contentView.frame.origin偏移了scrollview.frame.origin多少;是系统计算得来的,计算方式由contentInsetAdjustmentBehavior决定。有以下几种计算方式:

UIScrollViewContentInsetAdjustmentAutomatic:如果scrollview在一个automaticallyAdjustsScrollViewContentInset = YES的controller上,并且这个Controller包含在一个navigation controller中,这种情况下会设置在top & bottom上 adjustedContentInset = safeAreaInset + contentInset不管是否滚动。其他情况下与UIScrollViewContentInsetAdjustmentScrollableAxes相同

UIScrollViewContentInsetAdjustmentScrollableAxes: 在可滚动方向上adjustedContentInset = safeAreaInset + contentInset,在不可滚动方向上adjustedContentInset = contentInset;依赖于scrollEnabled和alwaysBounceHorizontal / vertical = YES,scrollEnabled默认为yes,所以大多数情况下,计算方式还是adjustedContentInset = safeAreaInset + contentInset

UIScrollViewContentInsetAdjustmentNever: adjustedContentInset = contentInset

UIScrollViewContentInsetAdjustmentAlways: adjustedContentInset = safeAreaInset + contentInset

当contentInsetAdjustmentBehavior设置为UIScrollViewContentInsetAdjustmentNever的时候,adjustContentInset值不受SafeAreaInset值的影响。

三、tableView何时会发生偏移问题

最常见的场景:tableview的frame超出了安全区域,而且设置了tableview的contentInset,第一幅图中的tableview的frame设置为(0,0,self.view.frame.size.width,self.view.frame.size.height),contentInset设置为UIEdgeInsetsMake(64,0,0,0);从而导致了adjustedContentInset 偏移了一个safeAreaInset + contentInset,简单来说:当tableview的frame超出安全区域之后,系统会自动调整tableview的显示范围,但此时又设置了contentInset属性导致出现下移现象。

四、解决方案

1.去掉contentInset

因为在iOS 11中系统已经默认对scrollview的显示做了处理只要其超过安全区域,它的内容显示都会在view上正常显示,所以就不需要设置contentInset,避免发生偏移。

2.设置contentInsetAdjustmentBehavior

在不改变contentInset的情况下通过设置tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;让adjustContentInset值不受SafeAreaInset值的影响。

3. iOS 11 ViewController新增的属性 addtionalSafeAreaInset;

在不改变contentInset的情况下通过增加安全区域的范围来抵消掉SafeAreaInset的值,如果SafeAreaInset值为(20,0,0,0),那么设置additionalSafeAreaInsets属性值为(-20,0,0,0),则SafeAreaInsets不会对adjustedContentInset值产生影响

4.把tableview的frame控制在安全区域内且不设置contentInset

在我的项目中对基类控制器中添加了一个ContentView属性,该View的区域范围也就是安全区域的范围,需要做的就是先算出View的高度,把tableview放到安全区域内就可以了,这样也有个好处就是,iOS 11只对scrollview进行了安全区域的显示处理,如果是view的话超出安全区域外的内容是无法显示的。

这里说一下automaticallyAdjustsScrollViewInsets这个属性,在iOS 11之前即使把tableview放到了可视范围之内(有NavigationBar且没有设置contentInset),当该属性为YES时候tableview还是会发生偏移。。。(很尴尬,所以这个属性我一般至为NO,瞬间觉得iOS 11做了一件很美好的事情)

对于安全区域高度的计算有必要说一下,仅在竖屏有NavigationBar的情况下,传统的iPhone尺寸安全区域高度为SCREEN_HEIGHT-64 ;而iPhoneX中为SCREEN_HEIGHT-(44+44+34),(第一个44为iPhoneX状态栏的高度,第二个为NavigationBar的高度,第三个为底部非安全区域的高度,iPhoneX比较特殊,并且WWDC上有明确说明对iPhoneX上view的显示必须放在安全区域之内)。

五、一些体会

最近看了很多WWDC17的视频,Swift4越来越稳定、XCode9以及iOS 11的变化真的很大而且充满很多新的特性,XCode9支持了无线调试、断电增强等功能开发起来越来越方便,iOS 11的众多新功能ARKit、Core ML等,让AR技术、机器学习和人工智能离我们越来越近。作为一名开发者来说最好的成长就是不断的填坑,本文借鉴了一些http://www.jianshu.com/p/efbc8619d56b文中的内容对此表示感谢,最后附上WWDC关于iPhoneX对于SafeArea的介绍:developer.apple.com/videos/play/fall2017/801/

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,233评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,013评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,030评论 0 241
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,827评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,221评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,542评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,814评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,513评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,225评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,497评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,998评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,342评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,986评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,812评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,560评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,461评论 2 266

推荐阅读更多精彩内容