學 Autolayout,當涉及到 ScrollView 時,很多人面對滿屏幕紅色錯誤不知所措,為什麼明明以前沒問題的約束到了這兒就成了錯誤。
比如下面這種情況:
一個藍色的 UIView,設其長寬約束分別為 210,200。上、左和右間距為 55。如此設置這個 View 的位置就被確定了。沒有錯誤,沒有警告。
可同樣的方法,到 UIScrollView 卻有觸目驚心的紅色錯誤:
可以看到 Storyboard 錯誤提示:ScrollView has ambiguous scrollable content height。這是怎麼一回事呢?
我們知道,UIScrollView 有一個 contentSize 屬性,其定義了 ScrollView 可滾動內容的大小。在以前用純代碼寫的時候,我們會直接對這個屬性賦值,定義其大小。但在 Autolayout 下,UIScrollView 的 contentSize 是由其內容的約束來定義的。因此,我們在 ScrollView 裡面設置的約束,不僅起到布局內容的作用,同時也起到了定義 ScrollView 可滾動范圍的作用。
針對上面的例子具體來說,ScrollView 知道它裡面有個 View,其高度是 200,距離頂上為 55,但僅通過這兩個約束沒辦法知道它的 contentSize 的高度是多少,我們缺少一個定義 View 到 ScrollView 底部距離的約束。
我們添加這樣的一個約束,值為 55。注意這裡看著有點怪,這個約束看著很長,但其實它的值並不大。
通過這個約束,ScrollView 現在可以得到其 contentSize 的高度了,即從頂端開始到 View 的間距 55,View 的高度 200,View 到底端間距 55。contentSize 的高也就是這些值的合:310。
另外要提的是,在這裡我們給了 View 一個很明確的高度約束(200)。缺少這個約束,ScrollView 是無法得到 contentSize 的。但對於某些控件,例如 UILabel,UIImageView,它們的尺寸是可以通過其內容決定的。
這種情況下,我們只需要上下左右的約束即可。但有時,他們的內容是運行時決定的,比如 UIImageView,如果它的圖片是運行時動態從服務器下載的,那麼我們就會放一個空的 UIImageView,不包含所顯示的圖片。可惜,這麼做,錯誤又來了。
由於未定義顯示的圖片,因此該 ImageView 的尺寸無法確定,所以 storyboard 傻傻地又拋出了錯誤。
那麼除了隨便放上一張圖片以外,還有沒有其他更正常的辦法?
我們可以用一個臨時的占位尺寸來告訴 storyboard,在你這裡就按照這個尺寸走。這個占位尺寸僅在 storyboard 設計階段有效,不會影響到運行時的尺寸。
通過修改 Intrinsic Size 為 Placeholder,現在錯誤沒了。
Autolayout 的使用是個熟能生巧的過程,相信每個人在一開始試著使用時,都會遇到滿屏警告的情況。通過多實踐,這種情況會慢慢得到改善最終避免出現。當你啪啪啪設置好約束,然後按一下 alt+cmd+= 後看著控件完全按照你想的樣式去布局,也是蠻爽的。