上一期,介绍了一下 Autolayout 的一些基本做法,以及 iOS 上 AutoLayout 的思想和简单的原理介绍,有同学给我建议继续出下一期,这里,我们就来继续第二期吧,这一期我们依然停留在 Interface Builder(后面简写 IB)上,介绍我在工作中遇到的一些问题,以及依赖 IB 是如何解决的,也不会涉及很多代码。
有时候,我们在拖拽完成布局后,总想看看效果怎么办呢?IB 给我们提供了预览功能,在 Assistant 编辑器中文件选择 preview 就可以看到 IB 布局后界面的预览效果了,而且可以添加多个设备,以及添加横屏和竖屏的效果。
有时候会遇到这样的问题,我的 View 要平均分布在界面上怎么办,比如下图的界面,我想让那五个 view 平均的分布在视图上怎么办呢?
做法其实大家可能已经想到了,那就是设置每个 View 宽度相等,并且间距为0。
这么看好像没啥用啊,除了红蓝红蓝相间以外,那么在平时使用过程中可以实现下面的布局效果:
其实在没有内容的情况下 UILabel 的大小会变成0,这是因为,UILabel 是由 Content 决定大小的 View,所以在没有文字的时候,他的大小就变成0了,可以利用这点来简单实现布局时,如果有标题那么显示标题,如果没标题,那么减少空隙的效果。
好多同学很不喜欢在 IB 里面用 ScrollView,原因是 SrollView 的大小,和他的 ContentView 的大小,很不好通过 IB 来决定,之后经过一段时间的研究找到了一个前辈通过代码添加新的约束来解决的方法-> UIScrollView 使用 Autolayout <-看的时候,估计要自带梯子,回到正题,既然本篇是 IB 技巧,那么我们就会用最少量的代码来解决问题,对于这个问题,经过一段时间的研究后,其实是不需要代码的我们来继续。
ScrollView 的大小是非常容易确定的,但是 ContentView 的大小就不好确定了,所以我们的目标就是在 IB 中确定 ContentView 的大小,这样就不需要再通过代码添加约束来设定 ContentView 的大小了
这里通过 IB 确定 ContentView 大小的额方法有两个,第一个是确定 ContentView 里面所有 View 的大小,来支撑 ContentView 的大小,这个方法应该是很常用了,我们来讲第二个方法,直接通过 ScrollView 的大小来确定 ContentView 的大小,这里假设我们需要 ContentView 和 ScrollView 一样大,跟着 View 的大小变化而变化,以适应不同的屏幕大小
如图,一般我们使用 ScrollView 的时候是通过在 ScrollView 内部增加一个 View 并把 View 到 ScrollView 上下左右的距离设置为0,这样可以让 View 上下左右紧贴 ScrollView,但是这个时候是不满足约束条件的,因为这样是没办法确定 ContentView 大小的,那么接下来怎么办呢。
这里,有一个思维的局限,总觉的已经让 ContentView 的上下左右贴着 ScrollView 四边了,没办法继续做什么了。
就像上图操作就可以了,那么思维局限在那里呢,因为我们选中了 ContentView 再按着 Command 或者 Shift 是没办法在 IB 中同时选中 View 和他的父 View,或是跨层级选中 View 的,但是在 Outline View 中就可以,这样其实在 Outline View 中选中了 ContentView 和 ScrollView,使用 Pin 菜单(什么你不知道 Pin 菜单,速速戳这里看上期->戳我戳我<-)中的等宽等高也能实现相同的效果。
前两天和以前公司小伙伴聊天的时候,他说最后他用只有一行的 TableView 来解决这样的问题,那么他只需要决定 Cell 的大小就行了,并且在 iOS 8 以后,可以通过 Cell 的布局自动获得 Cell 的大小,这又是另一个解法了,对于 UI 来说只有想不到,没有做不到。
如果我们使用 Storyboard 的话,会有另外一个很方便的东西,那就是 Content 类型为 Static Cell 的 TableView,使用 Static Cell 的 TableView,我们可以快速的拖拽一个可以上下滚动的登录界面,设置界面,选项界面等等等等……就像这样。
在 View 比较复杂,并且部分 View 是可以重用的时候,我们这时候一般会通过把可以重用的 View 创建和事件处理都包装到子 View 中去创建,代码上似乎很容易理解,在 IB 中其实也有一样的方法,那就是通过指定 View 的 Class 来实现,但是如果我们要用 xib 创建和布局的 View 的话,方法就是在那个 View 的类中,初始化时加载对应的 xib 文件,但是每次都要写这个,好麻烦怎么办,有人把这个过程做了一下封装那就是-> UINibWraper <-。
就像上面,我有一个 View 是很多不同类型的 Cell 都需要的一个操作类型的 View,上面提供了点赞,评论,分享等功能,如果每个 Cell 都画上去的话,每次改的话,每个 Cell 都需要修改,这就不符合我们懒惰程序员的性格了,所以我创建了一个 View 提供这些功能,集成到所有的 Cell 上去。
IB 其实是我们拖拽对象的地方,也就是所有在 IB 上的东西都是对象,那么这里我放个平时我们很少用到的一个东西 NSObject,也就是截图下面这货:
这其实是为 IB 上的对象,添加一个对象用的占位符,也就是我们可以在我们的 ViewController 中通过 IB 来添加对象,我们可以给 TableView 一个单独的 Delegate,指定一个特定的对象,通过设置对象的 Class 和 Value 来实现不同的 TableView 在不同的对象中获取数据,这样代码里面就不用看到一个 ViewController 中有一堆的 TableView 的 Delegate 方法,让 ViewController 键减肥。
对于 UI 来说,只有想不到,没有做不到,很多方法都是聪明的码农们想出来的,欢迎大家丢砖。