嘗試在Storyboard中對UIScrollView使用autolayout自動佈局,遇到了種種麻煩,記錄一下
git
一、UIScrollView在StoryBoard中的佈局github
在StoryBoard中使用UIScrollView必定要用下圖中的這種佈局,若是剛開始沒想到用UIScrollView後來纔想加,能夠選中全部Subview而後選擇Editor - Embed in - Scroll View,ContentView忘加了也能夠相似操做,其它的設置可參考async
二、UIScrollView邊距的肯定佈局
通常狀況下一個View的邊距肯定是經過Leading, Trailing, Top, Bottom space肯定的,一般我是使用最快捷的方式:在StoryBoard中右鍵拖動出View與SuperView的線來選擇。可是若是對UIScrollView使用此方法,使其與SuperView邊緣重合,即設置邊距爲0,會發現怎麼也和SuperView對齊不了。測試
究其緣由,是由於有一個默認Margin的存在,UIScrollView四周的默認Margin是8。ui
解決方法是:不要用快捷方式,在StoryBoard的右下角,點自動佈局第二個的Pin圖標,在彈出的小窗口中去掉"Constrain to margins"的勾選,而後將其上的四個邊距設置爲0spa
三、Content View的約束必定要齊全.net
這個涉及到contentsize的大小,不全的話會出現很奇怪的問題,好比滑動不到底部。設計
當Content View中的內容高度不超過屏幕的高度時,能夠設置bottom爲1,不然就不會滑動了code
若是遇到提示「Has ambiguous scrollable content height」,就得考慮約束不全的問題了。好比你的scrollview底部有一個動態高度的label,設計爲與scrollview bottom的距離爲1,與其上的一個控件距離爲0,你想着label的高度由scrollview的高度來控制,即依賴scrollview的高度,豈不知scrollview的高度是根據內部subview的高度來計算的,也就是依賴於後者的。這種狀況就最好用代碼設置contentsize了。
當ContentView中的內容高度超過屏幕的高度時,該怎麼佈局呢?首先最大的問題超過屏幕的區域怎麼在StoryBoard中顯示出來,辦法是在StoryBoard中修改ViewController的size,以下圖:
另外一篇文章的經驗:UIScrollView 實踐經驗
但 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 的例子。
四、在代碼中修改contentsize
有時候contentsize多是動態的,須要在代碼中修改。一般是在ViewController的viewDidAppear方法中setContentsize。
可是在個人項目中發現一個問題,iPhone6/iPhone5測試正常,在iOS6中設置無效,設置時打印contentsize是正常的稍後打印contentsize.height竟然變爲0了,真是奇哉怪也。
最後是想起了這篇文章的方法,將setContensize放在dispatch_async(dispatch_get_main_queue(), ^{ });中解決問題
參考: