UIScrollView中的Autolayout

UIScrollView在使用的时候,会有许多让人意想不到的地方,譬如我们今天所要讲的这个问题。在UIScrollView添加子视图,并对子视图设置约束会经常出问题,那是因为UIScrollView本身的特性造成的。因为UIScrollView本身还有一个contentSize属性,用来表示内部滚动内容的大小,如果我们设置的约束无法让scroll view确认这个contentSize的话,那么我们设的约束就会报错。但是有一个比较不错的方法来处理这些问题,我们来看一下。

我们以创建一个垂直方向滚动的scroll view为例子,来讲一下如何设置autolayout会比较好,比较方便。

添加一个UIScrollView

首先我们新创建一个最简单的项目,然后在viewController里添加一个scrollView,并填充棕色,这样区分明显一点,并且我们对scroll view添加了上下左右4个约束,距离上下左右各多少距离。如下图添加一个UIScrollView

添加innerView

我们添加一个自定义的UIView作为scroll view的唯一的subview,同时我们也可以把它认为是一个真正包含我们需要子视图的容器view。这里我们姑且称它为innerView。我们除了要给他设置最简单的上下左右距离scroll view的约束,最重要的是我们要给它设置一个相对于scroll view等宽等高的约束。

先给innerView添加上下左右约束,让它距离scroll view每个边距离都是0,然后填充橘色,方便区分。如下图

添加上下左右约束

然后再给innerView添加相对于scroll view的等宽,等高约束。这样scroll view就能确定它的contentSize了。如下图

添加等宽等高约束

添加我们想要的元素

现在我们只需要往innerView里添加我们自己想要的子视图即可,所有添加的子视图都是相对于innerView来添加约束,innerView作为一个容器装载了我们需要的view,而上面我们已经把innerView相对于scroll view的约束添加好了。这样子就会方便很多。

我们先添加两个view,并且都设置好左,上,右3个距离边界的约束,然后再设置一个恒定高度的约束。如下图

添加两个子视图

重点来了,如果我们需要继续添加子视图,比如我们要添加一个redView,并且他的位置在whiteView的下面,scroll view已经无法显示他了,那怎么办?我们这样来:

首先,我们找到innerView的Equal Height约束,将它的Priority属性改为low(250),意思是将这个约束的优先级降低,这个约束是可选的,如果发现有其他约束和这个约束相冲突,那么会优先使用优先级高的约束。如下图

修改Priority

然后,我们对innerView添加一个恒定高度的约束,将原来的高度拉长,譬如设为1000,很明显这个约束和之前innerView的与scroll view等高的约束是冲突的,但是我们现在的恒定高度的约束优先级为Required(1000),是必要的约束,要高于原来的那个约束,就会优先使用恒定高度的约束。如下图

添加恒定高度约束

接下来,我们找到innerView距离scroll view上边界的约束Top Space,将它的值改为-300,改为其他值也行,反正就是要把innerView往上挪,把它下面原来被遮住的部分露出来,好让我们可以方便的添加视图即可。如下图

修改Top Space

于是,现在我们通过把innerView高度拉高,并且往上挪动,把下面原先被遮住的部分露了出来,现在我们就可以愉快的继续添加视图了,我们添加redView,如下图

添加redView

最后,当我们把所有要添加的子视图都添加好了,并且设置好约束以后,那么我们需要将innerView距离上边界的约束Top Space的值改回原来的0,这样才能正常显示,如下图

修改Top Space为正常值

至此,所有元素和约束添加完毕,运行后,scroll view能够按照我们的预期进行展示和滚动。

Demo运行后的效果如下

Demo运行效果

Author: Uncle Peter
Link: http://yoursite.com/2016/08/02/UIScrollView中的Autolayout/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.