Demo 地址 https://github.com/gityuency/DemoCode
前言:
去年有個項(xiàng)目需求,就是在App啟動的時候,彈出一個提示框。這個提示框在不同的屏幕上和四周的間距要差不多相同,里面有提示內(nèi)容,分為圖片和文字兩種。當(dāng)文字過多的時候,就滾動顯示。 當(dāng)時我用frame算的大小和坐標(biāo)。寫了3段基本重復(fù)的代碼來適應(yīng)不同的手機(jī)屏幕。很菜的設(shè)計(jì)。需求改動了好幾次,我也做的很狗血。以前有小伙伴 問我,怎么在XIB上拖一個ScrollView. 我也沒有弄出來. 今天看別人文章的時候,有所發(fā)現(xiàn),于是就試驗(yàn)了一下。這里只是記錄這種方案,或許不能滿足觀眾們的需求。
最近的拖拽研究
iOS - 如何在 XIB 中拖拽 ScrollView 2
第一步:
新建工程,這里我選擇 Swift 工程.
第二步:
我把 ViewController 的 View 顏色設(shè)置為黃色.
第三步:
拖拽一個 ScrollView 到 View 上,設(shè)置 ScrollView 的背景色為藍(lán)色,并添加約束, 這四個約束很普通的, 就是距離父視圖上,下,左,右,的邊距,但是在距離父視圖 下 邊距的選項(xiàng)里, 我選擇了參照 View, 而不是 Bottom Layout Guide http://ios.jobbole.com/82815
第四步:
我們需要放一個 ContentView 到這個 ScrollView 上面, ScrollView 的滾動是需要 ContentSize 的, 沒有 Size, 也就無法滾動. 之前看到網(wǎng)上說的拖拽 ScrollView 需要放一個 ContentView 基本都是這樣的套路,可惜他們約束添加的套路我沒看懂.這里我就選擇使用一個 View 當(dāng)做 ContentView.把這個 View 的顏色設(shè)置成為粉色.然后給這個 View 取個名字, 添加進(jìn)去了之后就能看到XIB 開始報(bào)錯了,說是 "有模糊的可以滾動的高度", 放著不用管, 我們來添加約束.
第五步:
給這個 ContentView 添加約束這里先添加四個約束:這里我添加的約束是距離父視圖(ScrollView)左,上,右邊的間距都是0,然后在添加一個高度約束,這個約束值就先取默認(rèn)的值.添加完了之后是有報(bào)錯的.
第六步:
在添加完了第五步的4個約束之后,仍然會有報(bào)錯,使用 XIB 給出的提示修復(fù)這個錯誤. 修復(fù)完錯誤之后,可以看到新增加了2個約束, 一個是在父視圖中水平居中(Horizontally in container),一個是添加了底部約束(Bottom space to), 如果不使用提示來修復(fù)這個錯誤, 直接自己添加也是可以的. 但是在我自己試驗(yàn)的時候, 是不知道需要這么做的, 只能是自己先加點(diǎn)約束, 等報(bào)錯, 然后按照提示來修復(fù)這些錯誤, 這里我只做了垂直滾動的視圖.
或者一步完成,直接添加6個約束:
上 / 下 / 左 / 右 / 高度 / 水平居中
第七步:
我們修改兩個約束值,
1,修改 Bottom Space to這個約束值, 原來的值是389, 這里改成0.
2,修改 Height Equals 這個約束值, 原來的值是128, 這里改成600
Bottom Space to這個約束值改成0之后, 正好就是這個內(nèi)容視圖(ContentView)完全填充在這個ScrollView 里面. Height Equals 指定了高度,就是給定了滾動的范圍, 這時候, ContentView 的高度大于 ScrollView 的高度, 所以在XIB 里面ContentView 的下面部分約束看起來會覺得超出了一樣,有點(diǎn)怪異,但并不要緊,我們先在模擬器里面運(yùn)行一下,上下滑動一下這個ScrollView, 發(fā)現(xiàn)一切都是正常的. 到這里,基本上就完成了添加一個ScrollView 的XIB 實(shí)現(xiàn)了. 但是會有一個不好的地方, 就是, 高度被我們固定成了600. 有些時候, ContentSize 是需要變化的, 我不希望在內(nèi)容顯示完的時候,滾動視圖下面還留出一堆空白.
第八步:
ScrollView 的高度比 ContentView 的高度小,導(dǎo)致不能完全操作這個 ContentView, 我想把 ContentView 完全顯示出來, 選中 View Controller -> 選中右上角標(biāo)尺 -> 把 Simulated Size 改成 "FreeForm" -> 更改高度為 900, 這時候控制器的 View 就被拉伸了, ScrollView 也跟著拉伸, 高度比 ContentView 大, 露出了藍(lán)色部分. 沒有關(guān)系, 不要在意. 運(yùn)行程序就沒有問題, 只是你看到的 XIB 效果如此而已.
第九步:
解決第七步留下來的問題, 添加一個 label.給這個 label 設(shè)置三個約束: 左,上,右的約束, 這個約束值自己指定一下就可以. 這里為了看出效果, 指定了如下值,留出空隙. 設(shè)置了 label 背景色為綠色, 把 number of lines 指定為0, 就能多行顯示, 隨便寫幾個字.
第十步:
運(yùn)行程序. 能看到如下效果, 上下滾動, 也是沒有意外的.
第十一步:
字少點(diǎn)的時候當(dāng)然沒有問題, 如果你試試多點(diǎn)字, 就變成了這個樣子:
第十二步:
重點(diǎn)來了, 做如下兩步:
1,給 label 添加一個底部約束(Bottom Space to) ,這個值我寫成和頂部約束一樣, 50,
2,刪除ContentView的高度約束 ( Height Equal )
然后看起來會是這個樣子,XIB中文本過長超出范圍,沒有關(guān)系,不要在意, 運(yùn)行程序就好了.如果你在意, 請按照第八步去修改 View 高度. 可以看到 label 距離 ContentView 50, 一切正常. 這個值你也可以修改成0, 或者你把label 的四個邊距都改成0. 進(jìn)行到此,差不多就完成了 XIB 拖放 ScrollView.
第十三步:
這是一些后續(xù)的實(shí)驗(yàn). 先添加一個按鈕到 控制器的 View 上. 在點(diǎn)擊按鈕的時候, 修改 label 的文字,
第十四步:
添加額外的控件. 在添加額外控件的時候需要注意保證 ContentView 能得出高度, 就沒有問題.
1, 添加一個新的 label, 約束和設(shè)置如下所示.
2,刪掉綠色背景 label 的 Top Space to 約束
3,重新添加綠色背景 label 的 Top Space to 約束, 這次的Top Space約束參照上一個 label, 在左側(cè)列表頁面, 選中綠色 label, 按住 ctrl 鍵,按住鼠標(biāo)左鍵拖動約束到公告 label, 選擇 "Vertical Spacting" 可以修改一下約束值, 這里改為20
然后運(yùn)行程序
后續(xù)
以上 ScrollView 拖拽完成, 我用了一個 View 來充當(dāng) ContentView. 這算是大家討論最多的做法. 根本原因是因?yàn)?ScrollView 包含了子 View 的時候,它就無法確定自己的 ContentSize 了.其實(shí)這個 ContentView 是可以給弄掉的. 直接弄一個 label, 然后設(shè)置 label 在 ScrollView 里面的四個邊距都是0, 照樣能很歡樂地滾動(水平滾動), ScrollView 里面你可以擺放任意多個控件, 它們在相互參照完成約束布局的最后, 要讓 ScrollView 能找到 ContentSize 就可以了.也就可以去掉那個 ContentView 了. 具體做法和示例代碼 可以參見這位 iOS 玩家的文章 -- 兩個 AutoLayout 的小建議
好吧,我還是再實(shí)驗(yàn)一下吧.
第一步:
新建一個工程, Swift, 給 View 添加一個 ScrollView, 設(shè)置背景色, 設(shè)置四個邊距約束, 這里我都設(shè)置為20,
第二步:
更改 ViewController 的顯示大小, 這里我寬高都改成1000,
第三步:
添加一個滑動條, 設(shè)置左,上,右邊距約束都是100, 設(shè)置滑動條寬度約束800. 這么做就確定了 ScrollView 的內(nèi)容寬度,如果和滑動條并排還有控件, 也要注意寬度值(有內(nèi)建高度的控件 label, button, 這樣的可以不用設(shè)置寬度)和右邊距約束.
第四步:
添加一個 label, 設(shè)置上下邊距約束為100, 這樣 ScrollView 的內(nèi)容高度就確定了. 設(shè)置一下寬度為100,把 number of lines 改成0,
第五步:
這時候 label 會有個報(bào)錯,說的是沒有 x 值. 我想讓這個 label 是在這個 ScrollView 水平居中的, 這時候添加一個和滑動條水平對齊的約束. 注意, 不能選擇 "Horizontally in container" 沒有效果的. 很詭異. 講道理, ScrollView 這個時候應(yīng)該是知道自己內(nèi)容有多寬的.
第六步:
運(yùn)行程序.把 ScrollView水平滾到中間
歡迎觀眾們交流討論,批評指導(dǎo)。
附上我曾經(jīng)拜訪過的文章:
1 - iOS 9 Auto Layout界面自動布局系列6-自適應(yīng)布局
2 - iOS學(xué)習(xí)筆記(5)-Auto Layout基本原理
3 - Autolayout 的第一次親密接觸 概要:
- IntrinsicContentSize
- 在Autolayout下使用Frame
- Autolayout什么時候計(jì)算frame
- Autolayout做動畫
- 當(dāng)View約束發(fā)生變化時,是怎么調(diào)整布局的
- 在Autolayout下使用Frame
- 何時使用updateConstraints