Demo 地址 https://github.com/gityuency/DemoCode
前言:
去年有个项目需求,就是在App启动的时候,弹出一个提示框。这个提示框在不同的屏幕上和四周的间距要差不多相同,里面有提示内容,分为图片和文字两种。当文字过多的时候,就滚动显示。 当时我用frame算的大小和坐标。写了3段基本重复的代码来适应不同的手机屏幕。很菜的设计。需求改动了好几次,我也做的很狗血。以前有小伙伴 问我,怎么在XIB上拖一个ScrollView. 我也没有弄出来. 今天看别人文章的时候,有所发现,于是就试验了一下。这里只是记录这种方案,或许不能满足观众们的需求。
最近的拖拽研究
iOS - 如何在 XIB 中拖拽 ScrollView 2
第一步:
新建工程,这里我选择 Swift 工程.
第二步:
我把 ViewController 的 View 颜色设置为黄色.
![](https://img.haomeiwen.com/i1235875/1fd5bc6c3ec806c3.png)
第三步:
拖拽一个 ScrollView 到 View 上,设置 ScrollView 的背景色为蓝色,并添加约束, 这四个约束很普通的, 就是距离父视图上,下,左,右,的边距,但是在距离父视图 下 边距的选项里, 我选择了参照 View, 而不是 Bottom Layout Guide http://ios.jobbole.com/82815
![](https://img.haomeiwen.com/i1235875/f2997071f0fd357b.png)
第四步:
我们需要放一个 ContentView 到这个 ScrollView 上面, ScrollView 的滚动是需要 ContentSize 的, 没有 Size, 也就无法滚动. 之前看到网上说的拖拽 ScrollView 需要放一个 ContentView 基本都是这样的套路,可惜他们约束添加的套路我没看懂.这里我就选择使用一个 View 当做 ContentView.把这个 View 的颜色设置成为粉色.然后给这个 View 取个名字, 添加进去了之后就能看到XIB 开始报错了,说是 "有模糊的可以滚动的高度", 放着不用管, 我们来添加约束.
![](https://img.haomeiwen.com/i1235875/e600ebf207c88049.png)
![](https://img.haomeiwen.com/i1235875/5da72154b018c8b7.png)
第五步:
给这个 ContentView 添加约束这里先添加四个约束:这里我添加的约束是距离父视图(ScrollView)左,上,右边的间距都是0,然后在添加一个高度约束,这个约束值就先取默认的值.添加完了之后是有报错的.
![](https://img.haomeiwen.com/i1235875/2c2df602e6775b78.png)
第六步:
在添加完了第五步的4个约束之后,仍然会有报错,使用 XIB 给出的提示修复这个错误. 修复完错误之后,可以看到新增加了2个约束, 一个是在父视图中水平居中(Horizontally in container),一个是添加了底部约束(Bottom space to), 如果不使用提示来修复这个错误, 直接自己添加也是可以的. 但是在我自己试验的时候, 是不知道需要这么做的, 只能是自己先加点约束, 等报错, 然后按照提示来修复这些错误, 这里我只做了垂直滚动的视图.
或者一步完成,直接添加6个约束:
上 / 下 / 左 / 右 / 高度 / 水平居中
![](https://img.haomeiwen.com/i1235875/def0556bdd93f9bc.png)
![](https://img.haomeiwen.com/i1235875/5abf12aed9be1579.png)
![](https://img.haomeiwen.com/i1235875/1fb507e40b1b1799.png)
第七步:
我们修改两个约束值,
1,修改 Bottom Space to这个约束值, 原来的值是389, 这里改成0.
2,修改 Height Equals 这个约束值, 原来的值是128, 这里改成600
Bottom Space to这个约束值改成0之后, 正好就是这个内容视图(ContentView)完全填充在这个ScrollView 里面. Height Equals 指定了高度,就是给定了滚动的范围, 这时候, ContentView 的高度大于 ScrollView 的高度, 所以在XIB 里面ContentView 的下面部分约束看起来会觉得超出了一样,有点怪异,但并不要紧,我们先在模拟器里面运行一下,上下滑动一下这个ScrollView, 发现一切都是正常的. 到这里,基本上就完成了添加一个ScrollView 的XIB 实现了. 但是会有一个不好的地方, 就是, 高度被我们固定成了600. 有些时候, ContentSize 是需要变化的, 我不希望在内容显示完的时候,滚动视图下面还留出一堆空白.
![](https://img.haomeiwen.com/i1235875/5ec850dcdbaf6201.png)
第八步:
ScrollView 的高度比 ContentView 的高度小,导致不能完全操作这个 ContentView, 我想把 ContentView 完全显示出来, 选中 View Controller -> 选中右上角标尺 -> 把 Simulated Size 改成 "FreeForm" -> 更改高度为 900, 这时候控制器的 View 就被拉伸了, ScrollView 也跟着拉伸, 高度比 ContentView 大, 露出了蓝色部分. 没有关系, 不要在意. 运行程序就没有问题, 只是你看到的 XIB 效果如此而已.
![](https://img.haomeiwen.com/i1235875/ff20ce83063c1f32.png)
第九步:
解决第七步留下来的问题, 添加一个 label.给这个 label 设置三个约束: 左,上,右的约束, 这个约束值自己指定一下就可以. 这里为了看出效果, 指定了如下值,留出空隙. 设置了 label 背景色为绿色, 把 number of lines 指定为0, 就能多行显示, 随便写几个字.
![](https://img.haomeiwen.com/i1235875/5ebded5fb7cde12c.png)
第十步:
运行程序. 能看到如下效果, 上下滚动, 也是没有意外的.
![](https://img.haomeiwen.com/i1235875/cfd9ff37fe989baa.png)
第十一步:
字少点的时候当然没有问题, 如果你试试多点字, 就变成了这个样子:
![](https://img.haomeiwen.com/i1235875/1037a7925bddef79.png)
第十二步:
重点来了, 做如下两步:
1,给 label 添加一个底部约束(Bottom Space to) ,这个值我写成和顶部约束一样, 50,
2,删除ContentView的高度约束 ( Height Equal )
然后看起来会是这个样子,XIB中文本过长超出范围,没有关系,不要在意, 运行程序就好了.如果你在意, 请按照第八步去修改 View 高度. 可以看到 label 距离 ContentView 50, 一切正常. 这个值你也可以修改成0, 或者你把label 的四个边距都改成0. 进行到此,差不多就完成了 XIB 拖放 ScrollView.
![](https://img.haomeiwen.com/i1235875/8081e2e7dbf6c9b0.png)
![](https://img.haomeiwen.com/i1235875/c32cda6354a5fba1.png)
![](https://img.haomeiwen.com/i1235875/6ec1efa00fe4dd06.png)
第十三步:
这是一些后续的实验. 先添加一个按钮到 控制器的 View 上. 在点击按钮的时候, 修改 label 的文字,
![](https://img.haomeiwen.com/i1235875/82d112c5be17a196.png)
![](https://img.haomeiwen.com/i1235875/525a73d55386d0fe.png)
第十四步:
添加额外的控件. 在添加额外控件的时候需要注意保证 ContentView 能得出高度, 就没有问题.
1, 添加一个新的 label, 约束和设置如下所示.
2,删掉绿色背景 label 的 Top Space to 约束
3,重新添加绿色背景 label 的 Top Space to 约束, 这次的Top Space约束参照上一个 label, 在左侧列表页面, 选中绿色 label, 按住 ctrl 键,按住鼠标左键拖动约束到公告 label, 选择 "Vertical Spacting" 可以修改一下约束值, 这里改为20
然后运行程序
![](https://img.haomeiwen.com/i1235875/ef27b45cb328e225.png)
![](https://img.haomeiwen.com/i1235875/6fb1415c183275d7.png)
![](https://img.haomeiwen.com/i1235875/318092c7ba658c33.png)
后续
以上 ScrollView 拖拽完成, 我用了一个 View 来充当 ContentView. 这算是大家讨论最多的做法. 根本原因是因为 ScrollView 包含了子 View 的时候,它就无法确定自己的 ContentSize 了.其实这个 ContentView 是可以给弄掉的. 直接弄一个 label, 然后设置 label 在 ScrollView 里面的四个边距都是0, 照样能很欢乐地滚动(水平滚动), ScrollView 里面你可以摆放任意多个控件, 它们在相互参照完成约束布局的最后, 要让 ScrollView 能找到 ContentSize 就可以了.也就可以去掉那个 ContentView 了. 具体做法和示例代码 可以参见这位 iOS 玩家的文章 -- 两个 AutoLayout 的小建议
好吧,我还是再实验一下吧.
第一步:
新建一个工程, Swift, 给 View 添加一个 ScrollView, 设置背景色, 设置四个边距约束, 这里我都设置为20,
![](https://img.haomeiwen.com/i1235875/ab521700f6edd0a5.png)
第二步:
更改 ViewController 的显示大小, 这里我宽高都改成1000,
![](https://img.haomeiwen.com/i1235875/138102687499385f.png)
第三步:
添加一个滑动条, 设置左,上,右边距约束都是100, 设置滑动条宽度约束800. 这么做就确定了 ScrollView 的内容宽度,如果和滑动条并排还有控件, 也要注意宽度值(有内建高度的控件 label, button, 这样的可以不用设置宽度)和右边距约束.
![](https://img.haomeiwen.com/i1235875/5f425a1eefd3ab5f.png)
第四步:
添加一个 label, 设置上下边距约束为100, 这样 ScrollView 的内容高度就确定了. 设置一下宽度为100,把 number of lines 改成0,
![](https://img.haomeiwen.com/i1235875/a0d2a143ac7368ab.png)
第五步:
这时候 label 会有个报错,说的是没有 x 值. 我想让这个 label 是在这个 ScrollView 水平居中的, 这时候添加一个和滑动条水平对齐的约束. 注意, 不能选择 "Horizontally in container" 没有效果的. 很诡异. 讲道理, ScrollView 这个时候应该是知道自己内容有多宽的.
![](https://img.haomeiwen.com/i1235875/a7a4d00b7445ab19.png)
第六步:
运行程序.把 ScrollView水平滚到中间
![](https://img.haomeiwen.com/i1235875/4e50055d56116dfd.png)
欢迎观众们交流讨论,批评指导。
附上我曾经拜访过的文章:
1 - iOS 9 Auto Layout界面自动布局系列6-自适应布局
2 - iOS学习笔记(5)-Auto Layout基本原理
3 - Autolayout 的第一次亲密接触 概要:
- IntrinsicContentSize
- 在Autolayout下使用Frame
- Autolayout什么时候计算frame
- Autolayout做动画
- 当View约束发生变化时,是怎么调整布局的
- 在Autolayout下使用Frame
- 何时使用updateConstraints
网友评论