ScrollView自動佈局的實現方式
阿新 • • 發佈:2018-12-29
背景
開發中,可能會有一些頁面顯示的元素很多,可能會超出一個螢幕,但也不適合用 TableView 或者 CollectionView,此時我們一般會用 ScrollView,那麼就會出現自動佈局的問題。
實現方式
純程式碼
特點
- 編碼繁瑣:需要手寫控制元件
- 安全:只要正確地設定約束或者 frame、contentSize,一般不會出現滾動問題
示例
lazy var scrollView: UIScrollView = {
let obj = UIScrollView(frame: CGRect(x: 0, y: 0, width: .screenW , height: self.screenH))
return obj
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(scrollView)
let subViewH: CGFloat = 400
let topView = UIView(frame: CGRect(x: 0, y: 0, width: enW, height: subViewH))
topView.backgroundColor = UIColor.red
scrollView.addSubview (topView)
let bottomView = UIView(frame: CGRect(x: 0, y: subViewH, h: screenW, height: subViewH))
bottomView.backgroundColor = UIColor.purple
scrollView.addSubview(bottomView)
scrollView.contentSize = CGSize(width: screenW, height: iewH * 2)
}
效果圖
Storyboard + 內部View
特點
- 搭建介面簡單
- 直觀
- 需要佔位檢視
頁面結構如圖
可能出現的問題
- ScrollView 中直接新增子元素,報錯:Has ambiguous scrollable content height
- ScrollView 內容超出螢幕仍不能滾動
實現滾動的程式碼
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
let statusBarH: CGFloat = 20
// 如果沒有導航欄,就返回狀態列的高度
let navH = gationController?.navigationBar.frame.maxY ?? statusBarH
let deltaH = (screenH - navH) - bottomView.frame.maxY
placeholderViewBottomConstraint.constant = deltaH
}
效果圖
Storyboard + 外部View
特點
- 搭建介面簡單
- 直觀
- 不需要佔位檢視,不需要對 ScrollView 的佈局做特殊處理
- 需要處理外部檢視的 frame(如果沒有使用者互動,可以忽略)
頁面結構如圖
可能出現的問題
- ScrollView 中直接新增子元素,報錯:Has ambiguous scrollable content height
- 當內容超出螢幕高度時,必須得設定 ContainerView 的 frame,否則不能滾動或者超出螢幕部分不接受事件
實現滾動的程式碼
override func viewDidLoad() {
super.viewDidLoad()
scrollView.addSubview(containerView)
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
var f = containerView.frame
f.size.width = screenW
// 這句程式碼很重要,處理超出螢幕無法響應事件問題
f.size.height = bottomView.frame.maxY
containerView.frame = f
scrollView.contentSize = CGSize(width: screenW, height: omView.frame.maxY)
}
效果圖
總結
ScrollView 不能滾動的原因
contentSize
小於自身 frame 的尺寸isScrollEnabled
屬性,不過它預設就是 true,預設無需設定- ScrollView 或者其父元素無法互動,此時我們需要檢查
isUserInteractionEnabled
屬性是否為 true
ScrollView 一直支援滾動
預設情況下,當 ScrollView 裡的元素不足一個螢幕高度時,不能滾動,如需滾動(彈簧效果),需要設定 alwaysBounceVertical
屬性為 true(水平方向亦如此)
關於 ScrollView 佈局的選擇
純程式碼佈局
如果是純程式碼佈局,只能用方式一。老老實實、一行一行程式碼實現佈局,雖然程式碼繁雜,但是坑少。(現在仍有不少公司是這樣程式設計的)
介面佈局
推薦方式三,這樣 ScrollView 和 其子元素分離,可以簡化很多約束問題,更直觀
以上程式碼,適用於 Swift 3.0 語法。