1. 程式人生 > >iOS中Xcode使用UIScrollView+AutoLayout輕鬆實現滾動佈局

iOS中Xcode使用UIScrollView+AutoLayout輕鬆實現滾動佈局

對於一些螢幕尺寸比較小的手機,或者內容很長,一螢幕顯示不了的情況,我們通常可以用手指往上滑的方法瀏覽底部內容,如果不是用ListView或者UITableView去實現的話,我們就需要自己實現滾動佈局。

Android實現

在Android平臺上,用XML檔案很容易實現滾動佈局,需要注意的是,ScrollView的下面只允許一個根檢視,譬如如下程式碼:

<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
    android:layout_width
="match_parent" android:layout_height="match_parent">
<Button android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> </ScrollView>

簡單分析一下,ScrollView的下面有一個LinearLayout,當然不允許有其他的佈局或者控制元件跟LinearLayout並列,你可以隨意在這個LinearLayout里加控制元件,是不是很簡單。

iOS實現

注意

回到iOS,當然我們也可以用程式碼的方式動態生成,對於習慣使用AutoLayout的我來說,覺得後者比較直觀而且可以很方便的進行各螢幕適配。但是在使用AutoLayout+UIScrollView的時候,發現很多坑,並沒有預想的簡單。

這裡就不再一一列出碰到的坑了,直接上乾貨,首先,我們得看官方的說明:

the scrollable size of a uiscrollview is computed automatically based upon the constraints of its subviews. in order to fully define the scrollable content width and height , there needs to be constraints touching all edges (leading ,trailing ,top, and bottom) of the scroll view.

簡單解釋一下就是:UIScrollView的可滾動尺寸是根據它的子檢視來決定的,為了計算可滾動的寬度和高度,需要約束 4個角落(左上右下)。

看到這裡,感覺跟Android的就不太一樣了,Android的只需要通過ScrollView中子檢視的高度就可以動態算出可滾動區域,而這裡還需要約束底部。其實有點不好理解,仔細想一想,其實這是很嚴謹的。

好了,下面我們開始佈局:

1、佈局UIScrollView

拖入UIScrollView,設定約束,讓ScrollView緊貼螢幕,如下圖:

這裡寫圖片描述

2、佈局UIScrollView的根檢視

我們直接往UIScrollView裡拖入UIView,命名為ContentView,讓ContentView作為UIScrollView的根檢視,而且是唯一的根檢視,其他的控制元件一律加入這個ContentView裡。看到這裡,其實是跟Android很像很像了。

回過頭來,在拖入UIView(ContentView)之後,可以看到出現了紅色的錯誤,有強迫症的同學看到這裡肯定會慌的,好吧,我們來消除這個錯誤。

設定ContentView的約束,上下左右也都是0,如下圖:

這裡寫圖片描述

再加上4個約束之後,依然有紅色錯誤,提示少約束。看到這裡,其實是很納悶兒的,我都設定好約束了,為啥還提示少。

解釋一下:UIScrollView的大小是根據它的子檢視來決定的,而剛才我們設定了ContentView相對於UIScrollView的約束。就相當於,要知道x的值首先需要知道y的值,現在是 要知道y的值必須知道x的值,陷入了矛盾之中。

不怕,我們有解決辦法,讓ContentView的大小暫時等於螢幕的大小,注意,這是暫時的,因為我們的內容隨時可能超過螢幕高度。為了消除這個紅點,我們也認了,按住control鍵,從ContentView拖線到View(Scroll View的父檢視),點選Equal Widths和Equal Heights,如下圖:

這裡寫圖片描述

可以看到,這樣設定之後,紅色變成了黃色,心情一下就好了,再更新一下,什麼色都沒了。

3、往ContentView里加入第一個控制元件

我們現在開始嘗試往ContentView里加入控制元件來模擬滾動,首先,拖入一個UILabel控制元件,並設定 左右上的約束(10, 10,10),如下圖:

這裡寫圖片描述

同時可隨意輸入點文字作為此Label的內容,並設定行數為0,如下圖:

這裡寫圖片描述

到這裡,我們也可以繼續加入各種控制元件,為了簡單,我們這裡直接加入最後一個控制元件。

4、往ContentView里加入最後一個控制元件

作為最後一個控制元件,我們可以讓它距離我們剛才加的第一個控制元件大一點,儘量讓它超出螢幕,好模擬可以滾動的效果。

拖入UIView,設定一個背景色,方便我們看到,之後我們來新增約束,
左:0, 上:900,右:0,高度200,如下圖:

這裡寫圖片描述

設定好之後,可能覺得這就完事了,可以出現滾動了,是這樣的麼? 我們在模擬器上執行試試,就在iPhone4S上瞅瞅效果吧。

執行之後,很遺憾,不能看到我們剛才新增的最後一個控制元件,這是為什麼呢? 還記得ScrollView的滾動區域是根據子檢視來決定的麼?在這裡,ContentView是作為ScrollView唯一的子檢視,而ContentView的高度我們設定了約束,是等於ScrollView的父檢視的,也就是螢幕的高。這樣一想,當然就不會出現滾動條了。

那麼,我們如何來配置,才能出現滾動效果呢? 我們繼續下面的最後步驟。

5、給ContentView的最後一個控制元件新增底部約束

在這裡,我們設定其底部約束為10,如下圖:

這裡寫圖片描述

設定好了之後,可以看到紅色錯誤又出現了。我們點進入看一下,原來是提示約束衝突了。如下圖:

這裡寫圖片描述

為什麼會出現這種情況呢?我們剛才說了,ContentView的高度是等於螢幕高的,但是現在卻不一樣了,是Label的高度+900+100+10,這肯定會衝突。

那麼,如何解決這種衝突呢? 我們只需要刪除ContentView.hegith = height即可。

點選紅色圓點,選中“ContentView.hegith = height”,點選Delete。
如下圖:

這裡寫圖片描述

刪除之後,出現了黃色圓點,我們更新一下,現在世界又清淨了。
這次能否達到效果呢?我們直接執行,很好,這次往下能順利看到最後一個View,如下圖:

這裡寫圖片描述

到這裡,我們已經順利的實現了UIScrollView+AutoLayout來實現滾動佈局。

總結

總結一下,關鍵的地方有兩個:

  1. UIScrollView的直接子檢視最好就一個
  2. ContentView中的最後一個控制元件一定要設定其底部約束

最後附上DEMO下載地址: