多個(gè)UIScrollView嵌套(瀑布流)

前言

之前有做一個(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)容。

效果圖

效果圖.gif

實(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。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容