xcode6中如何對scrollview進行自動布局(autolayout),xcode6scrollview

來源:互聯網
上載者:User

xcode6中如何對scrollview進行自動布局(autolayout),xcode6scrollview

Xcode6中極大的增強了IB中自動布局的能力,下面就通過對刺兒頭scrollview進行一次自動布局實戰,看看自動布局在Xcode6中到底值不值得使用:

說UIScrollView是個刺兒頭,實在沒有誇張,這是由於scrollview本身contentSize、contentInsets等複雜的特性導致,蘋果文檔在講autolayout的時候甚至專門拿出一節講如何對scrollview進行自動布局。國外有個哥們曾經那他遇到的布局問題請教蘋果員工,結果花費了40分鐘才得出可行的辦法:

When I had a chance to go talk to an actual Apple Engineer about AutoLayout last week at WWDC, I made sure to go. I thought of my most painful experience using AutoLayout recently – when I was making a login screen with username and password fields on a ScrollView (so it scrolls up when the keyboard comes up) – and had the Apple engineer walk me through the example.......This “simple” solution took the Apple Engineer 40 minutes to solve! However, several senior engineers I know said that they’ve never been able to get AutoLayout working quite right on a ScrollView, so 40 minutes is actually not bad! 【原文地址】

一、我們的需求是什嗎?

我們要如實現這樣一種布局:


整個視圖一共有三個組件:頭像(UIimageView)、文字(UILabel)、和一個UIScrollView。我們的布局預期是豎屏是整個view採用正常的上下結構;橫屏時則採用左右結構。

二、豎屏布局為了方便布局,對於在邏輯或者結構上比較緊密的多個視圖組件,我們往往採取化零為整的辦法,將多個view放在一個containerview中,讓這個父view獨自去應對外部情況的變化,將內部和外部隔絕開來,本例中,就是將頭像和文字label放入一個contanierview中的。這樣,我們布局的主要工作就集中在兩個組件之間了:頭像所在的containerview和scrollview。同樣的,對於scrollview中的子view,我們同樣也可以將其放在同一個父的container view中,然後將這個container view作為scrollview的子view也即content view,這樣我們對scroll view 的布局就可以簡化為對content view的布局,而content view裡面的子view相對於content view的布局就是普通的布局了,剩下的只需要我們解決好scroll view和content view的布局即可。開啟storyboard,首先對預設的size class進行布局(wAny, hAny)(關於size class的使用,詳見我上一篇博文),對頭像的container view添加四個約束以確定其frame (x, y, width, height),這四個約束分別是:水平置中、距頂端定長、定寬、定長,布局基本功不再多言,無非點擊、選中、設定......詳情請參見蘋果官文,布局解析見:
接下來就是對scrollview進行布局,我們知道scroll view除了自身的布局需要考慮(x, y, width, height)外,還有一個contentSize屬性也必須要在布局的過程中進行確定,contentSize是UIScrollView用於確定它所要展示的內容尺寸的大小,而這個contentSize在布局中實際上是又scroll view的子view :content view的寬和高實現的,注意: 我們不能將content view的寬和高的約束設定為由scroll view決定(如和scroll view等寬、等高),否則,Xcode會有警告:scroll view的content size不確定!


在這種情況下,我們必須要對content view的布局約束引入scroll view之外其他參照物,我們拖進來一個輔助的view作為參照物or錨點,如下:

在storyboard中,這三個view的層次是:

通過這個參考view,確定content view的寬度和高度,儘管content view的尺寸可以不依賴於scroll view,但我們還不得不設定content view 和其父view的關係:具體而言就是要確定content view和scroll view的top, bottom, leading和trailing contstraints,這個地方可能比較具有迷惑性,原因是蘋果對於這四個約束的使用在scroll view中做了變化:它不再是確定content view尺寸的依據,而是協助scroll view中content view四周的邊界(or你可以理解為留白),進而確定scroll view的contentSize屬性。

這樣,預設size class的布局就算完成了,(註:content view的子view的布局這裡不再詳述)。三、橫屏布局為了布局方便,我們首先將storyboard中view的尺寸調整為667 * 375, iphone 6 橫屏時的尺寸,然後將size class的height設定為compact模式(因為橫屏時,高度處於“壓縮”狀態),這樣我們就可以對橫屏的狀態進行單獨的布局,Xcode對自動布局通過size class的使用,靈活性大大提高(詳細說明參加我上一篇博文),不同size class下約束相互隔離,甚至另外一個size class下添加的view也是不可見的(not installed),這樣我們布局工作起來就大大的簡化了。



調整完view的尺寸後將size class設為(wAny, hCompact)

前面需求中提到,在橫屏模式我們希望中,將頭像和scroll view按照左右循序配置,這樣可以有效利用螢幕空間,給使用者最好的使用體驗(尤其是iphone6 & plus出來後)。

考慮橫屏的情況,我們不知道螢幕的具體寬度(實際從4s到6 plus可能有4種數值),我們想確定頭像和scroll view 的具體位置,這時,我們又要找一個參照物了,有了參照我們就能很好的確定各自的約束。這種參照物的思想在自動布局中有著廣泛的應用,它可以有效幫我們降低布局的複雜度、提高布局的靈活性。

我們仍然選取一個view作為參考物or 錨點,我們把它的位置放在整個螢幕的正中間,這個view我們稱之為:middle anchor view,頭像的trailing space和scroll view 的leading space就都可以以這個middle anchor view為錨確定x座標值了。


接著,頭像和scroll view以及content view的其他約束可以按照豎屏時的思路依次添加。布局完成後(紅色view即為anchor view,在布局完成之後可將該view隱藏):


注意,因為前面豎屏的時候我們使用了(wAny, hAny)的寬和高都任意的size class,它包含(wAny, hCompact)這種情況,因此,在上一個size class設定的布局元素在當前的size class中依然都存在,為了防止布局幹擾,我們可以將這些布局全部清除掉再重新布局:


可以方便的在storyboard中清除全部約束


全部布局完成後,編譯運行即可獲得前面需求中所示的效果。

四、總結1.布局之前考慮好需求是什麼,橫豎屏時的UI展示效果是什麼;2.布局UIScrollView的時候將其子view放在一個content view中去,簡化布局;3.布局content view的時候必須要引人第三方參照物(view),已確定其尺寸,注意不能根據scroll view 來確定content view的尺寸;4.一定要設定content view 相對於scroll view 的上下左右(top, bottom, leading, trailing)間距,這些設定不是為了確定content view的尺寸,而是協助scroll view 確定其contentSize;5.布局時注意一些小技巧的使用,可時布局工作事半功倍:a. 將多個view放入一個container view的化整為零思想;b. 引入參照物or 錨點,輔助定位、布局;


IOS開發中scrollview在布局限制下,怎更改它的contentsize值

應該就是勾選了autolayout選項,導致的。
在autolayout下,ios計算scrollview的contentsize的機制是略有不同的。

在autolayout下,會在viewDidAppear之前根據subview的constraint重新計算scrollview的contentsize。 這就是為什麼,在viewdidload裡面手動設定了contentsize沒用。因為在後面,會再重新計算一次,前面手動設定的值會被覆蓋掉。
解決辦法就是:
1.去除autolayout選項,自己手動設定contentsize
2.如果要使用autolayout,要麼自己設定完subview的constraint,然後讓系統自動根據constraint計算出contentsize。 要麼就在viewDidAppear裡面自己手動設定contentsize。
 
使用AutoLayout的時怎實現動畫

先解除約束,然後添加約束,然後layoutIfNeeded
 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.