Xcode6中如何对scrollview进行自动布局(autolayout)

本文转载至 http://www.cocoachina.com/ios/20141011/9871.html

Xcode6中极大的增强了IB中自动布局的能力,下面就通过对刺儿头scrollview进行一次自动布局实战,看看自动布局在Xcode6中到底值不值得使用。

说 UIScrollView是个刺儿头,实在没有夸张,这是由于scrollview本身contentSize、contentInsets等复杂的特性 导致,苹果文档在讲autolayout的时候甚至专门拿出一节讲如何对scrollview进行自动布局。国外有个哥们曾经那他遇到的布局问题请教苹果 员工,结果花费了40分钟才得出可行的办法:

When I had a chance to go talk to an actual Apple Engineer about AutoLayout last week at WWDC, I made sure to go. I thought of my most painful experience using AutoLayout recently – when I was making a login screen with username and password fields on a ScrollView (so it scrolls up when the keyboard comes up) – and had the Apple engineer walk me through the example.......This “simple” solution took the Apple Engineer 40 minutes to solve! However, several senior engineers I know said that they’ve never been able to get AutoLayout working quite right on a ScrollView, so 40 minutes is actually not bad! 【原文地址】

一、我们的需求是什么?

我们要如下图实现这样一种布局:

20140916174314525.png

整个视图一共有三个组件:头像(UIimageView)、文字(UILabel)、和一个UIScrollView。我们的布局预期是竖屏是整个view采用正常的上下结构;横屏时则采用左右结构。

二、竖屏布局

为 了方便布局,对于在逻辑或者结构上比较紧密的多个视图组件,我们往往采取化零为整的办法,将多个view放在一个containerview中,让这个父 view独自去应对外部情况的变化,将内部和外部隔绝开来,本例中,就是将头像和文字label放入一个contanierview中的。这样,我们布局 的主要工作就集中在两个组件之间了:头像所在的containerview和scrollview。同样的,对于scrollview中的子view,我 们同样也可以将其放在同一个父的container view中,然后将这个container view作为scrollview的子view也即content view,这样我们对scroll view 的布局就可以简化为对content view的布局,而content view里面的子view相对于content view的布局就是普通的布局了,剩下的只需要我们解决好scroll view和content view的布局即可。

打 开storyboard,首先对默认的size class进行布局(wAny, hAny)(关于size class的使用,详见我上一篇博文),对头像的container view添加四个约束以确定其frame (x, y, width, height),这四个约束分别是:水平居中、距顶端定长、定宽、定长,布局基本功不再多言,无非点击、选中、设置......详情请参见苹果官方文档,布局解析见下图:

20140916184238218.png

接下来就是对 scrollview进行布局,我们知道scroll view除了自身的布局需要考虑(x, y, width, height)外,还有一个contentSize属性也必须要在布局的过程中进行确定,contentSize是UIScrollView用于确定它所 要展示的内容尺寸的大小,而这个contentSize在布局中实际上是又scroll view的子view :content view的宽和高实现的,注意:我们不能将content view的宽和高的约束设定为由scroll view决定(如和scroll view等宽、等高),否则,Xcode会有警告:scroll view的content size不确定!

20140916191135554.png

在这种情况下,我们必须要对content view的布局约束引入scroll view之外其他参照物,我们拖进来一个辅助的view作为参照物or锚点,示意图如下:

20140916191949592.png

在storyboard中,这三个view的层次是:

20140916194355574.png

通过这个参考view,确定content view的宽度和高度,尽管content view的尺寸可以不依赖于scroll view,但我们还不得不设定content view 和其父view的关系:具体而言就是要确定content view和scroll view的top, bottom, leading和trailing contstraints,这个地方可能比较具有迷惑性,原因是苹果对于这四个约束的使用在scroll view中做了变化:它不再是确定content view尺寸的依据,而是帮助scroll view中content view四周的边界(or你可以理解为留白),进而确定scroll view的contentSize属性。

20140916193847468.png

这样,默认size class的布局就算完成了,(注:content view的子view的布局这里不再详述)。

三、横屏布局

为了布局方 便,我们首先将storyboard中view的尺寸调整为667 * 375, iphone 6 横屏时的尺寸,然后将size class的height设置为compact模式(因为横屏时,高度处于“压缩”状态),这样我们就可以对横屏的状态进行单独的布局,Xcode对自动 布局通过size class的使用,灵活性大大提高(详细说明参加我上一篇博文),不同size class下约束相互隔离,甚至另外一个size class下添加的view也是不可见的(not installed),这样我们布局工作起来就大大的简化了。

20140916195150907.png

调整完view的尺寸后将size class设为(wAny, hCompact)

前面需求中提到,在横屏模式我们希望中,将头像和scroll view按照左右顺序布局,这样可以有效的利用屏幕空间,给用户最好的使用体验(尤其是iphone6 & plus出来后)。

考虑横屏的情况,我们不知道屏幕的具体宽度(实际从4s到6 plus可能有4种数值),我们想确定头像和scroll view 的具体位置,这时,我们又要找一个参照物了,有了参照我们就能很好的确定各自的约束。这种参照物的思想在自动布局中有着广泛的应用,它可以有效的帮我们降 低布局的复杂度、提高布局的灵活性。

我们仍然选取一个view作为参考物or 锚点,我们把它的位置放在整个屏幕的正中间,这个view我们称之为:middle anchor view,头像的trailing space和scroll view 的leading space就都可以以这个middle anchor view为锚确定x坐标值了。

20140916200711745.png

接着,头像和scroll view以及content view的其他约束可以按照竖屏时的思路依次添加。布局完成后如图所示(红色view即为anchor view,在布局完成之后可将该view隐藏):

20140916200741250.png

注意,因为前面竖屏的时候我们使用了(wAny, hAny)的宽和高都任意的size class,它包含(wAny, hCompact)这种情况,因此,在上一个size class设置的布局元素在当前的size class中依然都存在,为了防止布局干扰,我们可以将这些布局全部清除掉再重新布局:

20140916201432789.png

可以方便的在storyboard中清除全部约束

全部布局完成后,编译运行即可获得前面需求中所示的效果。

四、总结

1.布局之前考虑好需求是什么,横竖屏时的UI展示效果是什么;

2.布局UIScrollView的时候将其子view放在一个content view中去,简化布局;

3.布局content view的时候必须要引人第三方参照物(view),已确定其尺寸,注意不能根据scroll view 来确定content view的尺寸;

4. 一定要设置content view 相对于scroll view 的上下左右(top, bottom, leading, trailing)间距,这些设置不是为了确定content view的尺寸,而是帮助scroll view 确定其contentSize;

5.布局时注意一些小技巧的使用,可时布局工作事半功倍:

  a. 将多个view放入一个container view的化整为零思想;

  b. 引入参照物or 锚点,辅助定位、布局.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/298760.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux文件读保护,Linux Rootkit实现文件保护

一个非常基础的rootkit,禁止读取指定文件编译系统:CentOS 7uname -r3.10.0-957.21.3-el7.x86_64#include #include #include asmlinkage long(*real_open)(const char __user *filename, int flags, unsigned short mode);unsigned long **syscall_table NULL;char…

python的网页解析器_python 之网页解析器

一、什么是网页解析器 1、网页解析器名词解释 首先让我们来了解下,什么是网页解析器,简单的说就是用来解析html网页的工具,准确的说:它是一个HTML网页信息提取工具,就是从html网页中解析提取出“我们需要的有价值的数据…

写一个聊天辅助程序

Codeprocedure TForm1.Button1Click(Sender: TObject);varhParent,hButton,hMemo: HWND;beginMemo1.SelectAll;//Memo内容全选Memo1.CopyToClipboard;//把Memo中选中的语句拷贝到剪贴板中try//找发送消息的QQ窗口hParent : FindWindow(nil, 发送消息);//然后找回话时用的编辑窗…

真是个狠人!开学第一天,这批小学生的造型刷爆朋友圈!

全世界只有3.14 % 的人关注了爆炸吧知识在史上最长的长假过后杭州一二三年级小学生回到学校忘记座位在哪里、老师姓什么各种有趣故事不断……而在养正小学门口,从入校门开始,大家笑声就不断,别样的开学礼一下刷屏了朋友圈:每个小朋…

C++中如何读取一个数的位数_C语言编写程序求水仙花数

C语言编写程序求水仙花数水仙花数是一个数学问题,其实质是一个三位数,个位数的立方加十位数的立方加百位数的立方之和等于这个三位数本身。例如153=1*1*15*5*53*3*3,即153=112527。这是一个相对较为简单的C程序&#x…

RabbitMQ简介和六种工作模式详解

一、RabbitMQ简介是一个开源的消息代理和队列服务器,用来通过普通协议在完全不同的应用之间共享数据,RabbitMQ是使用Erlang(高并发语言)语言来编写的,并且RabbitMQ是基于AMQP协议的。1.1 AMQP协议Advanced Message Queuing Protocol(高级消息…

为什么男性比女性死得更早,心疼一秒钟!

最近娱乐圈的那些大瓜大家都吃了吗?某明星的运动?黑眼圈??不免让小编想起之前看的文章 男性为啥比女性“去”的早嗯,有可能是操劳过度 生活太累 咳咳咳咳咳以上均是不负责任猜想吃瓜要谨慎呦????不过这篇报道…

(转)C#网络编程(基本概念和操作) - Part.1

源码下载:http://www.tracefact.net/SourceCode/Network-Part1-2.rar C#网络编程(基本概念和操作) - Part.1 引言 C#网络编程系列文章计划简单地讲述网络编程方面的基础知识,由于本人在这方面功力有限,所以只能提供一些初步的入门知识&#x…

jwt如何防止token被窃取_在吗?认识一下JWT(JSON Web Token)?

什么是JSON Web Token ?官网介绍:JSON Web Token(JWT)是一个开放标准(RFC 7519),它定义了一种紧凑且自包含的方式,用于在各方之间安全地将信息作为JSON对象传输。由于此信息是经过数字签名的,因此可以被验证和信任。可…

8月日更,我的困难与感悟

8月份参加了掘金的日更活动,坚持每天写技术文章进行分享,现在活动结束了,来复盘下这一个月来我的困难与感悟。8月日更其实刚开始我是不想参加这个活动的,最近确实比较忙,不管是工作还是自己的私事,都不允许…

那些神一样的学习技巧,专治各种不服!

▲ 点击查看著名的俄国生理学家曾反复对自己的学生提过这个要求:“应当先学会观察,观察。不学会观察,你就永远当不了科学家。”鲁迅也曾这样教导:“如果要创作,第一要观察。”在《神探夏洛克》中,有这么一段…

kafka 怎么样连接图形化界面_图形化编程有多简单,点亮LED不到一分钟

Arduino编程在所有单片机当中应该说是最简单的了,但是还可以更加简单。比如说图形化编程,图形化编程真正让Arduino大众化了,因为谁都可以通过图形化编程方式来制作自己需要的小玩意。啃萝卜关于图形化编程软件有很多,我独宠啃萝卜…

linux驱动内核哪个文件夹,linux设备驱动归纳总结(一):内核的相关基础概念...

linux设备驱动归纳总结(一):内核的相关基础概念1. 内核与 linux 设备驱动的作用与关系内核:用于管理软硬件资源,并提供运行环境。如分配 4G 虚拟空间等。linux 设备驱动:是连接硬件和内核之间的桥梁。linux 系统按个人理解可按下划…

怪不得超市不让带宠物...

1 难怪超市不让带狗啊▼2 医学生的聊天记录过于硬核▼3 你身边的外卖小哥头盔上都顶着什么呢?▼4 表妹非要把猫脸P到蜜蜂身上▼5 其实主要还是看脸脸到位了,祖安小公举问题都不大▼6 就你们这个送别方式我觉得他是回不来了......▼7 妹妹沦为工具…

自定义控件复选框和单选框的实现

我们先实现单个按钮,为了复用,不管单选还是复选按钮都是使用同一个类来实现,为了区别单选还是复选,我们用一个自定义枚举类型CheckButtonStyle属性style来区别,当其值设置为CheckButtonStyleDefault或CheckButtonStyle…

单文件组件的组件传值_移动端组件化架构(下)

我的组件化方案对于项目架构来说,一定要建立于业务之上来设计架构。不同的项目业务不同,组件化方案的设计也会不同,应该设计最适合公司业务的架构。架构设计以我之前公司项目为例,项目是一个地图导航应用,业务层之下的…

为什么圆是360度?超颠覆的解释

圆为什么有360度?为什么不是300度呢?古文明时期人类把很多不能解释的自然现象归结为“天意”真的有天意吗?我们把圆分成等份,奇迹出现了.....依次等分下去,结果一样...任何被分成等分的角度的所有数字之和为9现在我们来…

我获得“微软MVP”奖项,后续将会贡献更多技术内容

昨天晚上,我收到了微软总部发来的“恭喜获得MVP”的邮件。请点击【阅读原文】查看我的MVP Profile页面。有的朋友说“一直以为你早就是MVP了”。其实这么多年我做的技术贡献主要是录编程视频教程,而这些视频教程都是通过BT下载等方式传播,没有…

[Spring MVC] - InitBinder验证

Spring MVC使用InitBinder验证: 使用InitBinder做验证的情况一般会在此Controller中提交的数据需要有一些是业务性质的,也即比较复杂的验证情况下才会使用。大部份简单的表单验证,使用annotation验证即可以解决。 Annotation验证使用方法可参…

linux6.5进入救援模式,rhel6.5救援模式修复系统

如果系统中很多重要的部分被删除了例如/boot下的所有东西,则可以通过救援模式[rootdazzle1 桌面]# mkdir /backup[rootdazzle1 桌面]# cp /etc/fstab /backup/fstab  //先备份以下fstab文件,也可以不备份自己写[rootdazzle1 桌面]# rm -rf /boot/*  …