前言
之前有做一個(gè)滑動(dòng)效果類似支付寶首頁的樣式http://www.itdecent.cn/p/f7bee2e2d5c7, 我是放在一個(gè)tableView里面,也有一些同學(xué)是兩個(gè)scrollView嵌套使用。后面用零碎時(shí)間斷斷續(xù)續(xù)也研究了一下,效果相對(duì)更復(fù)雜一點(diǎn)。
需求
一個(gè)view顯示基本頁面信息;
一個(gè)浮選的view用于切換選擇內(nèi)容;
幾個(gè)ScrollView展示內(nèi)容。
效果圖

實(shí)現(xiàn)思路
頁面需要三層ScrollView,最下層兩個(gè)UIColletionView用來放瀑布流的數(shù)據(jù),中間層CollectionContainerScrollView放兩個(gè)ColletionView以便方便左右滑動(dòng),最上層用來包含所有的NestContentScrollView,用來上下滑動(dòng).另外需要注意Cell復(fù)用,之前的看的兩篇文章沒使用復(fù)用。
三層ScrollView最大的問題就是會(huì)滑動(dòng)沖突,在這里我的實(shí)現(xiàn)方式是第三層的ColletionView的scrollEnabled設(shè)為NO,中間層ScrollView的contentSize不大于它的frame一樣,當(dāng)最上層的ScrollView滑動(dòng)的時(shí)候,改變對(duì)應(yīng)子view的frame。
實(shí)現(xiàn)過程
最上面的headerView、兩個(gè)button的懸浮的pinnedView、滾動(dòng)條的位置和下拉刷新的位置的效果效果實(shí)現(xiàn)方式和這個(gè)http://www.itdecent.cn/p/f7bee2e2d5c7實(shí)現(xiàn)方式一樣,這里就不贅述了。
中間層CollectionContainerScrollView的frame是變化的,當(dāng)最大的NestContentScrollView滑動(dòng)的時(shí)候,依據(jù)pinnedView的位置來改變CollectionContainerScrollView的frame,當(dāng)pinnedView懸浮在頂部的時(shí)候CollectionContainerScrollView的frame.size則不變,改變的是ColletionView的ContentOffse。具體代碼實(shí)現(xiàn)如下:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
CGFloat nestScrollViewContentOffsetY = self.nestScrollView.contentOffset.y;
if(nestScrollViewContentOffsetY <= 0.0){
_nestScrollView.headerView.frame = (CGRect){.origin=CGPointMake(0, nestScrollViewContentOffsetY),.size= _nestScrollView.headerView.bounds.size};
_nestScrollView.pinnedView.frame = (CGRect){.origin=CGPointMake(0, nestScrollViewContentOffsetY+Nest_HeaderScrollView_Height),.size=CGSizeMake(Main_Screen_Width, Nest_PinneView_height)};
}else if(nestScrollViewContentOffsetY >= Nest_HeaderScrollView_Height){ //pinnedView懸浮的距離
_nestScrollView.pinnedView.frame = (CGRect){.origin=CGPointMake(0, nestScrollViewContentOffsetY),.size=CGSizeMake(Main_Screen_Width, Nest_PinneView_height)};
_nestScrollView.collectionContainerScrollView.frame = (CGRect){.origin=CGPointMake(0, nestScrollViewContentOffsetY+Nest_PinneView_height), .size=CGSizeMake(_nestScrollView.collectionContainerScrollView.frame.size.width, Main_Screen_Height-(App_Navigation_Height+App_Status_Height)-Nest_PinneView_height)};
[_nestScrollView.currentColletionView setContentOffset:CGPointMake(0, nestScrollViewContentOffsetY-Nest_HeaderScrollView_Height)];
}else{
_nestScrollView.pinnedView.frame = (CGRect){.origin=CGPointMake(0, Nest_HeaderScrollView_Height),.size=CGSizeMake(Main_Screen_Width, Nest_PinneView_height)};
_nestScrollView.collectionContainerScrollView.frame = (CGRect){.origin=CGPointMake(0, Nest_HeaderScrollView_Height+Nest_PinneView_height), .size=CGSizeMake(_nestScrollView.collectionContainerScrollView.frame.size.width, Main_Screen_Height-(App_Navigation_Height+App_Status_Height)-(Nest_HeaderScrollView_Height+Nest_PinneView_height)+nestScrollViewContentOffsetY)};
[_nestScrollView.currentColletionView setContentOffset:CGPointZero];
}
}
注意點(diǎn)
當(dāng)我們左右滑動(dòng)或者點(diǎn)擊按鈕切換CollectionContainerScrollView的時(shí)候,我們需要把兩個(gè)collectionView的ContentOffset設(shè)置為0,同時(shí)也要改變NestContentScrollView的contentSize。
總結(jié)
整個(gè)上下滑動(dòng)的時(shí)候只有最大的NestContentScrollView可以滑動(dòng),NestContentScrollView的contentSize根據(jù)當(dāng)前展示和ColletionView的contentSize、pinnedView、headerView和MJ加載更多的高度總和。當(dāng)切換或者其他一個(gè)改變時(shí),NestContentScrollView的contentSize也需要改變。
不足
這樣的實(shí)現(xiàn)會(huì)有一個(gè)問題 那就是非??焖倩瑒?dòng)pinnedView的時(shí)候 有可能中間會(huì)出現(xiàn)一些小空隙。另外工程中瀑布流的CollectionView沒有使用到懶加載,有興趣的同學(xué)可以一起完善一下。demo鏈接https://github.com/Dolphii/NestScrollView。