情景:
项目中的滑动视图,随处可见,可能大家一般的做法是只要是滑动视图,都采用tableView做,但是我想说的是,其实很多滑动视图都可用在xib上用scrollView做,而不需要用表,比如设置页面,个人中心,商品详情页,所有的只要它的内容不是动态加载的,或者不需要重用的,都可以在xib上用scrollView做,在项目中,我很多都是是这么干的,只要不需要重用的列表,统统采用xib在scrollView上做,
好处:不需要像表那样,每个区域都要定制一个cell,然后还要写一堆代理,并且判断不同的行返回不同的cell。
缺点:如果要在列表上加一块区域(需求什么的)确实没有表方便,因为表的cell是分开的,而xib上的scrollView都是集中在内容视图上的,它只有那么一块空间,当然也有解决方法,就是把新加的一块拿出来放到一个view里面,然后用代码把它加在scrollView预留的一块很小区域,运行的时候改变这块区域高度就可以
切入正题,看下面两种情况
一横向滚动
这个可以直接在xib上画,如下
contentView是拖上去的,不是自带的,那么为什么要拖一个内容视图上去呢,其实scrollView的滚动完全是靠内容视图实现的,假如scrollView是横向滚动,那么只有当内容视图的宽度大于scrollView的宽度时,它才能横向滑动,小于或者等于的话,它是滑不了的,这和表创建时的原理类似,先看有多少个cell,在看每个cell的高度,其实就是计算所有cell所占的内容视图的高度来决定表是否可滑,只有当所有cell的高度之和大于表的高度时候,表才可以滑动,不然是滑动不了的
要想滑动视图可以滑动,以可以横向滑动为例,那么必须满足两个条件
1 contentView所占的区域最终是确定的(也就是contentView的宽度和高度),就是contentSize最终要确定
2 contentView的width也就是contentSize.width必须大于滑动视图的宽度
contentView的宽高要确定,通过谁来确定,肯定是通过contentView上面的子视图,利用它的子视图把它的宽度或者高度给撑起来,就像之前一篇讲的自动布局技巧篇-文字横向扩展父视图跟随横向扩展,下图,这个label的父视图的宽度就是通过label撑起来的,它的父视图宽度是没有给的,换句话说,它的父视图的宽度是通过子视图label确定的,那么理解了这一点,那么scrollView的contentView的宽高(contentSize)的确定和这个本质上是一样的,只不过这里label只确定了父视图的宽度,而父视图的高度不是由它确定的,要改简单,直接把父视图的高度约束去掉,把label垂直居中约束去掉,给它上面下面各一个固定约束就可以确定父视图的高度,
所以按照这个思路,让scrollView横向滑动,给scrollView里面的contentView的子视图设置约束只需要遵守下面的约定即可:
横向:每个子视图的宽度要确定(不管你是给固定值,还是相对于屏幕,或者参照view来确定),各个子视图之间左右距离要给定,最左边和最右边子view距离contentView的距离给定,所有子视图横向约束之和一定要大于滑动视图的宽度
纵向:每个子视图的高度要确定(不管你是给固定值,还是相对于屏幕,或者参照view来确定),各个子视图距离contentView的上下距离给定,纵向有多个子视图,每个子视图都有一个纵向约束之和(每个子视图高度+上下距离),那么要求最大的那个和小于等于滑动视图的高度
如下:
上面是scrollView横向滚动,再来看纵向滚动
具体操作如下:
横向:每个子视图的宽度要确定(不管你是给固定值,还是相对于屏幕,或者参照view来确定),各个子视图距离contentView的两边距离给定,横向有多个子视图,每个子视图都有一个横向约束之和(每个子视图宽度+左右距离),那么要求最大的那个和小于等于滑动视图的宽度
纵向:每个子视图的高度要确定(不管你是给固定值,还是相对于屏幕,或者参照view来确定),每个子视图之间上下距离要给定,最上边和最下边子视图距离contentView距离给定,所有子视图纵向约束之和一定要大于滑动视图的高度
如下:
而其他要注意的约束就是contentView距离父视图scrollView的约束,一般都是上下左右距离都为0,当然如果你要在scrollView里面一部分区域滑的话,那就不是0,就是具体的值,
demo地址https://github.com/aszkj/KJAutoLayoutSillDemo