場(chǎng)景分析
在實(shí)際開發(fā)中遇到UIScrollView的場(chǎng)景大概分為兩類: 超過一個(gè)豎屏的信息展示 和 輪播圖眼五,以少數(shù)派App做個(gè)例子
技術(shù)難點(diǎn)
通常來說,UIScrollView的布局 有兩種方法:
- StoryBoard + AutoLayout的方式
- 代碼 + SnapKit布局的方式 進(jìn)行
不管我們采取哪種布局技術(shù)泞遗,如果我們直接在UIScrollView中添加子視圖,然后給子視圖相對(duì)于UIScrollView添加約束席覆,會(huì)發(fā)現(xiàn)子視圖是無法顯示的史辙,這是什么原因呢?
其實(shí)是因?yàn)椋?UIScrollView的leading/trailing/top/bottom是相對(duì)于自己的ContentSize來說的佩伤,而不是Frame; 而在給所有子視圖添加完視圖前ContentSize還不確定聊倔,我們這時(shí)候又給子視圖添加約束到ContentSize,相互依賴生巡,不就成了蛋生雞耙蔑,雞生蛋的問題了。
解決方案
我們可以給UIScrollView添加一個(gè)充滿自己的ContainerView孤荣,然后我們所有子視圖的布局相對(duì)于這個(gè)ContainerView就好了甸陌; 同時(shí),只要確定了ContainerView的尺寸盐股,也就確定了UIScrollView的ContentSize
干起來
我們通過SnapKit + 代碼的方式給一個(gè)垂直滾動(dòng)的UIScollView加約束來做例子钱豁,其他情況原理都是類似的。
- Step1: 給UIScollView添加約束,沒什么可說的
view.addSubview(scrollView)
scrollView.snp.makeConstraints { (make) in
make.edges.equalToSuperview()
}
- step2 : 給UIScollView添加一個(gè)充滿他的ContainerView(重要)
注意:ContainerView給定了寬度疯汁,即UIScollView的ContentSize的寬度
確定了牲尺,還需要確定高度
scrollView.addSubview(containerView)
containerView.snp.makeConstraints { (make) in
make.edges.equalToSuperview()
make.width.equalTo(ScreenWidth)
}
Step3: 在ContainerView中添加子視圖
//add 5 orange view
for i in 0..<5 {
let orangeView = UIView()
orangeView.backgroundColor = #colorLiteral(red: 0.9372549057, green: 0.3490196168, blue: 0.1921568662, alpha: 1)
containerView.addSubview(orangeView)
orangeView.snp.makeConstraints({ (make) in
make.left.right.equalTo(containerView)
make.height.equalTo(orangeViewGap)
if i == 0 {
make.top.equalTo(containerView.snp.top).offset(orangeViewGap)
} else if let previousView = containerView.subviews[i-1] as? UIView{
make.top.equalTo(previousView.snp.bottom).offset(orangeViewGap)
}
if i == 4 {
containerView.snp.makeConstraints({ (make) in
make.bottom.equalTo(orangeView.snp.bottom).offset(orangeViewGap)
})
}
})
}
上面代碼中,第一個(gè)View很簡單幌蚊,關(guān)鍵是最后一個(gè)子視圖谤碳,一定要加好最后一個(gè)子視圖到ContainerView的間隔溃卡,即我們確定了ContainerView的高度
,那么我們就確定了UIScrollView的ContentSize的高度
蜒简,到此瘸羡,完成整個(gè)布局過程; 核心代碼都在上面臭蚁。
最終最铁,完成效果如下: