UIScrollView及其AutoLayout
之所以要把UIScrollView单独拿出来说,是因为UIScrollView在AutoLayout时是一个比较特殊的视图。它特殊就特殊在它的Top、Trailing、Head、Bottom是相对于它的ContentSize来设置的,而不是它的bounds来设置的。
同时,要实现视图的滚动,UIScrollView就得先知道要滚动的视图(UIScrollView的子视图)的大小,这样才能够正确计算它要显示的各种数据(比如滚动条的大小、分页的多少)。
这样,你也许就不会好奇当你给UIScrollView的子视图添加好Top,Trailing,Head,Bottom约束时,为什么Xcode还是会提示有错误了。
因为你添加的子视图要根据UIScrollView的ContentSize确定大小,而UIScrollView的ContentSize又要根据UIScrollView的子视图确定其自身的大小。就这样,谁也不能确定自己的大小,所以Xcode就只能选择报错了。
使用AutoLayout的正确姿势
要解决上面的相互矛盾的问题。我们可以先在UIScrollView上添加一个名叫ContentView的子视图,让它根据UIScrollView的宽和高(UIScrollView的宽和高还是根据它自身的bounds来确定的)来确定自身的大小,然后让UIScrollView通过ContentView来确定它的ContentSize,再然后,把要添加的子视图添加到ContentView上来,让子视图们根据ContentView来确定自己的大小和位置。
这样,UIScrollView的ContentSize的大小也确定了,子视图的大小和位置也确定了,大家皆大欢喜,算是大功告成。
但是,还是会有那么一点点的小瑕疵在里面。
阻止ContentView的向下偏移
之所以说有点小瑕疵在里面是因为当你按照上面的方法都把约束添加好了以后,比如说像下面ScrollView这样:
和ContentView这样:
在这里我让ContentView与UIScrollView等高等宽,ContentSize的Top,Bottom,Head,Trailing分别等于ContentView的对应属性,但是运行后却发现变成了下面这个样子:
这里我把ContentView的背景色设置成了蓝色以便于观察。
你会发现ContentView向下偏移了一段距离。
原来,从iOS7开始,只要UIScrollView是ViewController的第一个子视图,并且顶部的导航栏不隐藏时,UIScrollView中的子视图就会自动往下偏移64个像素,在这里UIScrollView的子视图就是ContentView了,所以ContentView就会向下偏移了64像素。
要解决这个问题现在有下面两个方法:
- 不让
UIScrollView成为第一个子视图。 - 调用
self.automaticallyAdjustsScrollViewInsets = NO代码关掉自动偏移的功能。
本文深入探讨了UIScrollView在AutoLayout中的特殊性,解释了为何在设置子视图约束时会出现错误,提供了正确的实现姿势及解决子视图向下偏移问题的方法。

846

被折叠的 条评论
为什么被折叠?



