1. 程式人生 > >在Storyboard中對UIScrollView使用autolayout自動佈局應該注意的地方

在Storyboard中對UIScrollView使用autolayout自動佈局應該注意的地方

嘗試在Storyboard中對UIScrollView使用autolayout自動佈局,遇到了種種麻煩,記錄一下

1、UIScrollView在StoryBoard中的佈局

在StoryBoard中使用UIScrollView一定要用下圖中的這種佈局,如果剛開始沒想到用UIScrollView後來才想加,可以選中所有Subview然後選擇Editor - Embed in - Scroll View,ContentView忘加了也可以類似操作,其它的設定可參考

這裡寫圖片描述

2、UIScrollView邊距的確定

一般情況下一個View的邊距確定是通過Leading, Trailing, Top, Bottom space確定的,通常我是使用最快捷的方式:在StoryBoard中右鍵拖動出View與SuperView的線來選擇。但是如果對UIScrollView使用此方法,使其與SuperView邊緣重合,即設定邊距為0,會發現怎麼也和SuperView對齊不了。

究其原因,是因為有一個預設Margin的存在,UIScrollView四周的預設Margin是8。

解決方法是:不要用快捷方式,在StoryBoard的右下角,點自動佈局第二個的Pin圖示,在彈出的小視窗中去掉”Constrain to margins”的勾選,然後將其上的四個邊距設定為0

3、Content View的約束一定要齊全

這個涉及到contentsize的大小,不全的話會出現很奇怪的問題,比如滑動不到底部。

當Content View中的內容高度不超過螢幕的高度時,可以設定bottom為1,否則就不會滑動了

如果遇到提示“Has ambiguous scrollable content height”,就得考慮約束不全的問題了。比如你的scrollview底部有一個動態高度的label,設計為與scrollview bottom的距離為1,與其上的一個控制元件距離為0,你想著label的高度由scrollview的高度來控制,即依賴scrollview的高度,豈不知scrollview的高度是根據內部subview的高度來計算的,也就是依賴於後者的。這種情況就最好用程式碼設定contentsize了。

當ContentView中的內容高度超過螢幕的高度時,該怎麼佈局呢?首先最大的問題超過螢幕的區域怎麼在StoryBoard中顯示出來,辦法是在StoryBoard中修改ViewController的size,如下圖:

但 UIScrollView 在 Auto Layout 是一個很特殊的 view,對於 UIScrollView 的 subview 來說,它的 leading/trailing/top/bottom space 是相對於 UIScrollView 的 contentSize 而不是 bounds 來確定的,所以當你嘗試用 UIScrollView 和它 subview 的 leading/trailing/top/bottom 來互相決定大小的時候,就會出現「Has ambiguous scrollable content width/height」的 warning。正確的姿勢是用 UIScrollView 外部的 view 或 UIScrollView 本身的 width/height 確定 subview 的尺寸,進而確定 contentSize。因為 UIScrollView 本身的 leading/trailing/top/bottom 變得不好用,所以我習慣的做法是在 UIScrollView 和它原來的 subviews 之間增加一個 content view,這樣做的好處有:

不會在 storyboard 裡留下 error/warning

為 subview 提供 leading/trailing/top/bottom,方便 subview 的佈局

通過調整 content view 的 size(可以是 constraint 的 IBOutlet)來調整 contentSize

不需要 hard code 與螢幕尺寸相關的程式碼

更好地支援 rotation

Sample 中的 AutoLayout 演示了 UIScrollView + Auto Layout 的例子。

這裡寫圖片描述

這裡寫圖片描述

4、在程式碼中修改contentsize

有時候contentsize可能是動態的,需要在程式碼中修改。通常是在ViewController的viewDidAppear方法中setContentsize。

但是在我的專案中發現一個問題,iPhone6/iPhone5測試正常,在iOS6中設定無效,設定時列印contentsize是正常的稍後列印contentsize.height居然變為0了,真是奇哉怪也。

最後是想起了這篇文章的方法,將setContensize放在dispatch_async(dispatch_get_main_queue(), ^{ });中解決問題

參考: