UIScrollViewj盡管繼承于UIView,但它是一個(gè)相對(duì)比較特殊的視圖,特別是當(dāng)它遇到了AutoLayout之后。在UIScrollView中使用AutoLayout的目的除了使用相對(duì)約束確定子控件的位置和大小外,更重要的是如何自動(dòng)計(jì)算出UIScrollView的contentSize(關(guān)于使用UIScrollView并且最終手動(dòng)指定contentSize的AutoLayout用法不再今天討論之列,嚴(yán)格意義上來(lái)說(shuō)這也不是一種真正的UIScrollView的AutoLayout應(yīng)用)。
UIScrollView的特殊之處
所謂UIScrollView的特殊之處就在于當(dāng)它遇到了AutoLayout之后其contentSize的計(jì)算規(guī)則有些特殊。首先contentSize是根據(jù)子視圖的leading/trailing/top/bottom進(jìn)行確定的,而子視圖的位置約束又必須依賴于UIScrollView來(lái)確定。這就有點(diǎn)類似于前面UICollectionView自適應(yīng)高度文章中提到的:UICollectionViewCell的大小計(jì)算就是計(jì)算contentView的大小,而contentView的大小計(jì)算依賴于子視圖的leading/trailing/top/bottom,子視圖的位置約束又依賴于contentView,此時(shí)只要子視圖存在固有尺寸(intrinsicContentSize)或者指定了尺寸又設(shè)置了leading/trailing/top/bottom,AutoLayout布局引擎即可計(jì)算出contentView的大小。
再回到AutoLayout,其實(shí)它的contentSize計(jì)算原理和UICollectionViewCell自適應(yīng)很是類似,只是UIScrollView內(nèi)部并沒(méi)有一個(gè)contentView的東西(但是可以想象其存在,方便后面的理解,不過(guò)要清楚UIScrollView滾動(dòng)的本質(zhì)并非包含一個(gè)contentView而是通過(guò)bounds和frame坐標(biāo)體系轉(zhuǎn)換來(lái)實(shí)現(xiàn)的),只要設(shè)置子視圖的leading/trailing/top/bottom(通常是通過(guò)edges=0讓子視圖上下左右間距都為0保證整個(gè)視圖都在UIScrollView可視范圍之內(nèi)),然后通過(guò)設(shè)置size(width/height)約束確定子視圖大小進(jìn)而由AutoLayout反向計(jì)算出UIScrollView的contentSize。
假設(shè)A是UIScrollView(藍(lán)色)、B是子視圖1(綠色)、C是子視圖2(綠色)、D是contentSize的計(jì)算區(qū)域(灰色,事實(shí)上它不存在),要想讓cotentSize可以自動(dòng)計(jì)算只需要確定B、C上下左右布局間距,然后再指定B、C間距和尺寸之后AutLayout既可以自動(dòng)推斷出contentSize的大小,原理如下圖(下圖布局類似于下面Demo3):