contentInsetAdjustmentBehavior各个值之间的区别

iOS11也出了不少时候了网上说适配的文章一大堆。
关于contentInsetAdjustmentBehavior这个参数之间的区别,好像没什么人能说明。
往下看的前提是你已经知道什么是安全区域,没看明白这个请出门左转WWDC2017编号204(16分20秒开始)。

以下内容是基于腾讯Bugly的iOS 11 安全区域适配总结内容扩展而来。(原文网址:https://mp.weixin.qq.com/s/W1_0VrchCO50owhJNmJnuQ)

这里写了个Demo目的是解释清楚contentInsetAdjustmentBehavior这个参数的值都是干啥的。
这个Demo的基本原则就是列出所有ScrollView的ContentSize和SaveArea的关系。

github地址:

https://github.com/biosli/ScrollViewContentInsetAdjustmentBehaviorDemo

基础代码

UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame: self.view.bounds];
scrollView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;

UIImage *testImg = [UIImage imageNamed: @"aaaa"];
UIImageView *imageView = [[UIImageView alloc] initWithImage: testImg];

[self.view addSubview: scrollView];

简单叙述页面关系:
就是一个ViewController里面放一个ScrollView,ScrollView里面包含了一个UIImageView。aaaa是张大图。

一、UIScrollViewContentInsetAdjustmentScrollableAxes

例1:

//以下全部例子,请在iPhoneX模拟器上查看。
//UIScrollViewContentInsetAdjustmentScrollableAxes例1
//如果scrollView的ContentSize很小,则不考虑安全区域
CGRect frame = imageView.frame;
frame.size.width = 300;
frame.size.height = 300;
imageView.frame = frame;
[scrollView addSubview: imageView];

scrollView.contentSize = imageView.frame.size;

scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentScrollableAxes;

例1图:

这两个地方忽略了安全区域。

例2:

//UIScrollViewContentInsetAdjustmentScrollableAxes例子2,横屏查看
//如果scrollView的ContentSize大于超出显示范围,则计算安全区域
CGRect frame = imageView.frame;
frame.size.width = 300;
frame.size.height = 600;//图片拉长,超出屏幕范围
imageView.frame = frame;
[scrollView addSubview: imageView];

scrollView.contentSize = imageView.frame.size;

scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentScrollableAxes;

例2图:

被拉长了,纵向可以滚动,横向宽度不够不能滚动。

红色是横向方向,不可滚动,安全区域被忽略。

例3:

    //UIScrollViewContentInsetAdjustmentScrollableAxes例子3,接上例,横屏查看
    //如果强制横向滚动,则计算安全区域
    CGRect frame = imageView.frame;
    frame.size.width = 300;
    frame.size.height = 600;//图片拉长,超出屏幕范围
    imageView.frame = frame;
    [scrollView addSubview: imageView];

    scrollView.contentSize = imageView.frame.size;
        //强制横向滚动
    scrollView.alwaysBounceHorizontal = YES;

    scrollView.contentInsetAdjustmentBehavior =  UIScrollViewContentInsetAdjustmentScrollableAxes;

例3图:

强制横向滚动,两个方向的安全区域都会被考虑到。

二、UIScrollViewContentInsetAdjustmentAutomatic

    //UIScrollViewContentInsetAdjustmentAutomatic例子,横屏查看
    //对照UIScrollViewContentInsetAdjustmentScrollableAxes例1
    //就算不够高度,也会空出上下两部分的安全区域。
    CGRect frame = imageView.frame;
    frame.size.width = 300;
    frame.size.height = 300;
    imageView.frame = frame;
    [scrollView addSubview: imageView];

    scrollView.contentSize = imageView.frame.size;

    scrollView.contentInsetAdjustmentBehavior =  UIScrollViewContentInsetAdjustmentAutomatic;

例图:

图片很小,不够撑满屏幕,但是用这个参数,会空出上下方向的安全区域。

其他的行为与UIScrollViewContentInsetAdjustmentScrollableAxes一致。

三、UIScrollViewContentInsetAdjustmentNever

    //UIScrollViewContentInsetAdjustmentNever例子
    //完全不考虑安全区域
    CGRect frame = imageView.frame;
    frame.size.width = 1000;
    frame.size.height = 1000;
    imageView.frame = frame;

    [scrollView addSubview: imageView];

    scrollView.contentSize = imageView.frame.size;

    scrollView.contentInsetAdjustmentBehavior =  UIScrollViewContentInsetAdjustmentNever;

例图:

Never了就是都不考虑安全区域了。

四、UIScrollViewContentInsetAdjustmentAlways

    //UIScrollViewContentInsetAdjustmentAlways例子
    //不管内容,全部考虑安全区域
    CGRect frame = imageView.frame;
    frame.size.width = 300;
    frame.size.height = 300;
    imageView.frame = frame;

    [scrollView addSubview: imageView];

    scrollView.contentSize = imageView.frame.size;

    scrollView.contentInsetAdjustmentBehavior =  UIScrollViewContentInsetAdjustmentAlways;

例图:

不管内容够不够大,全部考虑安全区域。

(对比UIScrollViewContentInsetAdjustmentScrollableAxes例1和UIScrollViewContentInsetAdjustmentAutomatic例子)

以下是适配建议:

对于完全自定义页面的安全区域是个碍事的东西,把ScrollView(及子类)的contentInsetAdjustmentBehavior设置成Never,自己控制每一个细节。

对于没有横屏需求的同学,系统默认的UIScrollViewContentInsetAdjustmentAutomatic是个好选择,就不用使用者自己修改了。

对于有横屏需求的同学,建议使用UIScrollViewContentInsetAdjustmentAlways,横屏的时候不会被“刘海”干扰。

PS:后面是一些有趣的阴谋论,关于为什么苹果放弃了之前的automaticallyAdjustsScrollViewInsets而强制使用新的SafeArea。

iOS 11是6月WWDC发布的,那时候这个接口(automaticallyAdjustsScrollViewInsets)就被禁掉了。9月份iPhoneX发布。 
当时,大家只知道苹果换了一套布局体系。 
从程序员角度看,6月份大家开始动手适配iOS11,开发人员不明所以,唾弃新体系的种种不便。9月份发布新的屏幕尺寸,新的体系发挥了价值,乖乖听话的开发人员已经适配完成了。 
从苹果角度看,6月份发布了新体系,但并没有透露新体系对新机型出来以后对适配的影响。9月份出新手机了,然后得意的看着开发者“叫你们丫不早适配”。 
这是一个中间组件提供方,强制修改接口的一个好办法。开发人员应该老老实实听苹果粑粑的话趁热适配新的iOS系统,而且要详细看每一个与老系统的对比,优先进行适配。

时间: 2024-08-11 19:19:09

contentInsetAdjustmentBehavior各个值之间的区别的相关文章

编写高质量代码改善C#程序的157个建议——建议28:理解延迟求值和主动求值之间的区别

建议28:理解延迟求值和主动求值之间的区别 要理解延迟求值(lazy evaluation)和主动求值(eager evaluation),先看个例子: List<int> list = new List<int>() { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; var temp1 = from c in list where c > 5 select c; var temp2 = (from c in list where c > 5 sele

[ css zoom和transform属性 ] zoom和transform属性中scale属性值之间的区别讲解及实例演示

IE和Chrome等浏览器与zoom 还在几年前,zoom还只是IE浏览器自己私有的玩具,但是,现在,除了FireFox浏览器,其他,尤其Chrome和移动端浏览器已经很好支持zoom属性了: zoom的字面意思是“变焦”,摄影的时候常用到的一个概念.对于web上的zoom效果,你也可以按照此概念理解.可以改变页面上元素的尺寸,属于真实尺寸. 在旧的web时代.*zoom: 1可以给IE6/IE7浏览器增加haslayout, 用来清除浮动,修复一些布局上的疑难杂症等. 其支持的值类型有: 百分

mysql 中execute、executeQuery和executeUpdate之间的区别

在用纯JSP做一个页面报警功能的时候习惯性的用executeQuery来执行SQL语句,结果执行update时就遇到问题,语句能执行,但返回结果出现问题,另外还忽略了executeUpdate的返回值不是结果集ResultSet,而是数值!特收藏如下一篇文章: JDBCTM中Statement接口提供的execute.executeQuery和executeUpdate之间的区别 Statement 接口提供了三种执行 SQL 语句的方法:executeQuery.executeUpdate 和

IOS之nil、Nil、NSULL、NULL之间的区别

其实早就想研究一下nil.Nil.NULL和NSNull之间的区别,只是工作上除了nil,其它的几乎少有用到,所以一直拖到今天.有时候感觉自己越来越浮躁,对细微处的知识理解不够深入,因此这里给自己提个醒--在以后的工作当中要始终保持一种钻研的精神! 言归正传,我们来分别介绍一下这四种类型: 一.nil 我们给对象赋值时一般会使用object = nil,表示我想把这个对象释放掉: 或者对象由于某种原因,经过多次release,于是对象引用计数器为0了,系统将这块内存释放掉,这个时候这个对象为ni

转载----execute、executeQuery和executeUpdate之间的区别

JDBCTM中Statement接口提供的execute.executeQuery和executeUpdate之间的区别 Statement 接口提供了三种执行 SQL 语句的方法:executeQuery.executeUpdate 和 execute.使用哪一个方法由 SQL 语句所产生的内容决定. 方法executeQuery 用于产生单个结果集的语句,例如 SELECT 语句. 被使用最多的执行 SQL 语句的方法是 executeQuery.这个方法被用来执行 SELECT 语句,它几

MySQL与Oracle之间的区别

这是参考别人然后自己总结的关于两者之间的区别,方便自己记忆 1.首先Oracle数据库是大型数据库,功能很强大,性能也很优越,所以大型的开发项目一般使用的就是Oracle但同时他也是比较昂贵的;而MySQl呢?它是一个中小型数据库,是免费的;这是他们之间的大致区别; 在具体的使用上的区别是: 2.主键: MySQL是一般使用自动增长,只要在创建表的时候设置auto increment即可,MySQL的主键字段就可以实现自动增长; 而Oracle没有自动增长类型,主键一般使用序列号,在插入数据的时

Windows 1252和ISO 8859-1之间的区别(ISO 8859-1就是Latin-1,但1252与Latin1略有不同)

2.6.5. ANSI字符编码和Windows 1252 Windows为了支持英语和西欧字符,自己设计了一个编码,对应的在Code Page号是1252,被称为Windows 1252. Windows 1252的设计,是参考了ANSI草案(ANSI Draft). 而ANSI draft后来发展成为正式的国际标准:ISO 8859-1 即,Windows 1252是在其成为正式标准ISO 8859-1之前而设计的,因此很容易理解,Windows 1252和ISO 8859-1不是完全等同的.

数组去重,call、apply、bind之间的区别,this用法总结

一.数组去重,直接写到Array原型链上. 1 //该方法只能去除相同的数字 不会去判断24和'24'是不同的 所有数字和字符串数字是相同是重复的 2 Array.prototype.redup=function(){ 3 var obj={}; 4 for(var i=0;i<this.length;i++){ 5 var val=this[i]; 6 if(obj[val]==this[i]){ //如果发现重复的 7 this[i]=this[this.length-1]; //那就把最后

jquery中使元素显示和隐藏方法之间的区别

在实际的项目开发中,要使一个元素隐藏的方法有很多,比如css的多种属性和jquery的多种方法,虽然他们的作用都是使元素不可见,但是各个方法实现的原理是不一样的.下面主要介绍jquery各个元素隐藏方法之间的区别. 1.show()和hide() 使用hide()方法隐藏元素实际上是同时减少元素的高度.宽度以及不透明度,直到这三个属性为0,最后设置元素的css属性disolay:none.show()方法从上到下增大元素的高度,从左到右增大元素的宽度,同时增加内容的不透明度,直至元素完全显示.