話不多說扒腕,先上效果圖
為了實(shí)現(xiàn)上圖效果寞钥,需要將子UIScrollView的滾動(dòng)事件傳遞到父UIScrollView蚁廓,實(shí)現(xiàn)同步滾動(dòng)功能。
父子關(guān)系如下圖:
如果不做任何處理替蔬,系統(tǒng)僅會(huì)執(zhí)行子UIScrollView的滾動(dòng)事件告私,而父UIScrollView會(huì)停留在原地不動(dòng)。
處理方法
-
在子View中加入?yún)f(xié)議承桥,通過代理的方式實(shí)現(xiàn)事件傳遞
寫個(gè)協(xié)議~
protocol TestTableViewControllerDelegate {
func testScrollViewDidScroll(_ scrollView: UIScrollView)
}
在子View中添加代理并在滾動(dòng)事件中調(diào)用代理方法
var testTableViewdelegate: TestTableViewControllerDelegate?
func scrollViewDidScroll(_ scrollView: UIScrollView) {
testTableViewdelegate?.testScrollViewDidScroll(scrollView)
}
-
在父View實(shí)現(xiàn)代理方法
實(shí)現(xiàn)思路:
當(dāng)父View出于0 <
contentOffset.y
< 限制滾動(dòng)高度時(shí)驻粟,直接同步父子的滾動(dòng)距離,為了避免banner出現(xiàn)突然消失或者突然出現(xiàn)的情況凶异,使用0.1秒的動(dòng)畫效果進(jìn)行過度蜀撑。當(dāng)子View的
contentOffset.y
< 0, 或contentOffset.y
> 限制滾動(dòng)高度時(shí),執(zhí)行0.3秒的動(dòng)畫效果將父View滾動(dòng)到頂或滾動(dòng)到底剩彬。
let bannerHeight: CGFloat = 200//這是達(dá)到父ScrollView停止?jié)L動(dòng)的高度
func testScrollViewDidScroll(_ scrollView: UIScrollView) {
let contentOffsetY = scrollView.contentOffset.y
//當(dāng)容器高度低于scrollview的高度時(shí)
if scrollView.contentSize.height < scrollView.frame.height {
var y = self.scrollView.contentOffset.y + contentOffsetY
y = y <= 0 ? 0 : y
y = y >= bannerHeight ? bannerHeight : y
UIView.animate(withDuration: 0.1) {
self.scrollView.setContentOffset(CGPoint(x: 0, y: y), animated: false)
}
return
}
if contentOffsetY > 0 && contentOffsetY < bannerHeight {
UIView.animate(withDuration: 0.1) {
self.scrollView.contentOffset = scrollView.contentOffset
}
}
if contentOffsetY <= 0 {
UIView.animate(withDuration: 0.3) {
self.scrollView.setContentOffset(CGPoint.zero, animated: false)
}
}
if contentOffsetY >= bannerHeight {
UIView.animate(withDuration: 0.3) {
self.scrollView.setContentOffset(CGPoint(x: 0, y: self.bannerHeight), animated: false)
}
}
}
小結(jié)
當(dāng)然具體實(shí)現(xiàn)還是要看項(xiàng)目需求了酷麦,這里僅提供一個(gè)實(shí)現(xiàn)思路。如果有更好的思路喉恋,歡迎交流沃饶。