三種左右兩個(gè)列表聯(lián)動(dòng)效果

這個(gè)效果我們經(jīng)常會(huì)看到比如外賣(mài),電商App的分類(lèi)頁(yè)面上看到铛楣,大概就是這樣:


image.png

點(diǎn)擊左側(cè)列表右側(cè)會(huì)跳到指定位置刀荒,滑動(dòng)右側(cè)左側(cè)會(huì)跟著切換,就是這么個(gè)東西窄陡。

然后常見(jiàn)的交互效果有兩種炕淮。一種是像“餓了嗎”點(diǎn)餐那種,右側(cè)是一體的可以一直滑動(dòng)跳夭。第二種是像“網(wǎng)易嚴(yán)選”分類(lèi)那樣涂圆,右側(cè)多個(gè)列表们镜,然后使用pagingEnabled效果進(jìn)行切換的。感興趣的可以看看這兩種润歉。然后我這次做了一個(gè)在第二種上進(jìn)行優(yōu)化的效果模狭,算是第三種吧。下面我們就說(shuō)說(shuō)這三個(gè)效果都是怎么做的踩衩。

第一種

左側(cè)列表沒(méi)什么好說(shuō)的就是一個(gè)列表嚼鹉,使用table和Collection都是可以的(我是比較習(xí)慣使用Collection)。右側(cè)由于也是連貫滑動(dòng)的驱富,所以也使用一個(gè)Collection就可以了锚赤。數(shù)據(jù)上看,一般都是返回的一個(gè)對(duì)象集合褐鸥,集合里每個(gè)對(duì)象還有個(gè)子分類(lèi)的幾個(gè):

"list": [{
                "name": "大分類(lèi)"
                "list": [{
                    "name": "小分類(lèi)",
                    "img": "https:\/\/res2.kongfz.com\/app\/search\/channel\/xianzhuang.png?2021122817"
                }, {
                    "name": "小分類(lèi)",
                    "img": "https:\/\/res2.kongfz.com\/app\/search\/channel\/minguo.png?2021122817"
                }]
            },
            {
                "name": "大分類(lèi)"
                "list": [{
                    "name": "小分類(lèi)",
                    "img": "https:\/\/res2.kongfz.com\/app\/search\/channel\/xianzhuang.png?2021122817"
                }, {
                    "name": "小分類(lèi)",
                    "img": "https:\/\/res2.kongfz.com\/app\/search\/channel\/minguo.png?2021122817"
                }]
            }

        ]

這樣我們左側(cè)用外層的集合做數(shù)據(jù)线脚。右側(cè)根據(jù)兩層數(shù)據(jù)對(duì)列表進(jìn)行分組處理。外層對(duì)應(yīng)section里層對(duì)應(yīng)row叫榕。然后在點(diǎn)擊左側(cè)切換時(shí)跳轉(zhuǎn)到對(duì)應(yīng)的section浑侥,監(jiān)聽(tīng)右側(cè)滑動(dòng)的位置來(lái)刷新左側(cè)的選擇狀態(tài)就可以了。參考代碼如下:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    if (scrollView == _leftCollectionView ) {//如果是左側(cè)的直接返回
        return;
    }
    //舉例這個(gè)每一個(gè)必有header翠霍,所以使用header判斷的锭吨,取最小是因?yàn)榕袛帱c(diǎn)在屏幕頂部
    NSIndexPath *indexPath = [self getMinIndexPathForHeaderView];
    if (!indexPath) { // 沒(méi)有header的情況
        return;
    }
    KFZAuctionHeadCatModel *headerCatModel = [_categoryHomeModel.localCatList objectAtIndexCheck:indexPath.section];
    KFZAuctionFirstCatModel *currentCatModel = [_categoryHomeModel.localContaniner objectForKey:headerCatModel.localSuperId];
    if (currentCatModel.localSelected) {
        return;
    }
    _categoryHomeModel.localCurrentCatModel.localSelected = NO;
    currentCatModel.localSelected = YES;
    _categoryHomeModel.localCurrentCatModel = currentCatModel;
    [_leftCollectionView reloadData];
    WS(ws)
    [_leftCollectionView performBatchUpdates:nil completion:^(BOOL finished) {
        NSInteger row = [ws.categoryHomeModel.localModelData indexOfObject:currentCatModel];
        [ws.leftCollectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForRow:row inSection:0] atScrollPosition: UICollectionViewScrollPositionCenteredVertically animated:YES];
    }];
}
- (NSIndexPath *)getMinIndexPathForHeaderView{
    NSIndexPath *targetIndexPath;
    NSMutableArray *headerArray = [[_rightCollectionView indexPathsForVisibleSupplementaryElementsOfKind:UICollectionElementKindSectionHeader] mutableCopy];
    if (headerArray.count > 0) {
        NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"section" ascending:YES];
        NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:&sortDescriptor count:1];
        [headerArray sortUsingDescriptors:sortDescriptors];
        if (headerArray.count > 1) {
            targetIndexPath = [headerArray firstObject];
        } else {
            NSIndexPath *indexPath = [headerArray firstObject];
            UICollectionViewLayoutAttributes *attr = [_rightCollectionView.collectionViewLayout layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeader atIndexPath:indexPath];
            CGRect endFrame = [self.view convertRect:attr.frame fromView:_rightCollectionView];
            }
        }
    }
    if (!targetIndexPath){
        NSMutableArray *itemArray = [[_rightCollectionView indexPathsForVisibleItems] mutableCopy];
        targetIndexPath = [itemArray firstObject];
    }
    return targetIndexPath;
}

第二種

左側(cè)和數(shù)據(jù)其實(shí)和第一種一樣。主要是右側(cè)的處理不同寒匙,以為要有分頁(yè)效果零如,右側(cè)用一個(gè)Collection就不行了,我這里使用的Collection套Collection的結(jié)構(gòu)(底層是一個(gè)Collection它的cell的大小是整個(gè)顯示區(qū)域然后里再放Collection)锄弱,這樣在底層左右兩個(gè)Collection是一一對(duì)應(yīng)的考蕾。外層多個(gè)小的Collection正常滑動(dòng)会宪,底層右側(cè)Collection設(shè)置pageing效果就可以了肖卧。

第三種(第二種優(yōu)化版)

還是先看效果:


Mar-20-2022 11-04-44.gif

頁(yè)面大體結(jié)構(gòu)和第二種是一樣的。優(yōu)化的點(diǎn):
1.右側(cè)paging是怎么切換的掸鹅,“網(wǎng)易嚴(yán)選”是劃不動(dòng)了然后切換塞帐,低層Collection是沒(méi)有滑動(dòng)能力的切換的觸發(fā)是靠外層做的像加載下一頁(yè)效果一樣。然后我這里是通過(guò)底層自身的滑動(dòng)去切換的好處就是手動(dòng)往下拉的時(shí)候能看到下面數(shù)據(jù)(正常是白色的)巍沙。
2.點(diǎn)擊左側(cè)切換葵姥,從上往下切換時(shí),下一個(gè)外層列表默認(rèn)在頂部句携;從下往上切換時(shí)下一個(gè)外層列表默認(rèn)在底部榔幸。代碼如下:

- (void)collectionView:(UICollectionView *)collectionView willDisplayCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath{
    
    if (collectionView == self.rightCollectionView && collectionView.dragging) {
        KFZCategoryHomeRightCell *rightCell = (KFZCategoryHomeRightCell *)cell;
        if (indexPath.section >= self.selectIndex.section) {
            [rightCell scrollToTop];
        }else if (indexPath.section < self.selectIndex.section) {
            [rightCell scrollToBottom];
        }
    }
}

3.有一部分樓層合并
gif上可以看出來(lái),我這個(gè)有一部分是連貫滑動(dòng)。做法上其實(shí)是在數(shù)據(jù)上就把需要連貫滑動(dòng)的數(shù)據(jù)合并到一起削咆,然后在通過(guò)代理把外層的刷新回傳到底層做的牍疏,具體有不少要處理的點(diǎn),這里就不一一說(shuō)了拨齐,我覺(jué)得正常用不到這個(gè)鳞陨,,奏黑,

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末炊邦,一起剝皮案震驚了整個(gè)濱河市编矾,隨后出現(xiàn)的幾起案子熟史,更是在濱河造成了極大的恐慌,老刑警劉巖窄俏,帶你破解...
    沈念sama閱讀 219,427評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蹂匹,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡凹蜈,警方通過(guò)查閱死者的電腦和手機(jī)限寞,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)仰坦,“玉大人履植,你說(shuō)我怎么就攤上這事∏幕危” “怎么了玫霎?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,747評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)妈橄。 經(jīng)常有香客問(wèn)我庶近,道長(zhǎng),這世上最難降的妖魔是什么眷蚓? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,939評(píng)論 1 295
  • 正文 為了忘掉前任鼻种,我火速辦了婚禮,結(jié)果婚禮上沙热,老公的妹妹穿的比我還像新娘叉钥。我一直安慰自己,他們只是感情好篙贸,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布投队。 她就那樣靜靜地躺著,像睡著了一般歉秫。 火紅的嫁衣襯著肌膚如雪蛾洛。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,737評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音轧膘,去河邊找鬼钞螟。 笑死,一個(gè)胖子當(dāng)著我的面吹牛谎碍,可吹牛的內(nèi)容都是我干的鳞滨。 我是一名探鬼主播,決...
    沈念sama閱讀 40,448評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼蟆淀,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼拯啦!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起熔任,我...
    開(kāi)封第一講書(shū)人閱讀 39,352評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤褒链,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后疑苔,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體甫匹,經(jīng)...
    沈念sama閱讀 45,834評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評(píng)論 3 338
  • 正文 我和宋清朗相戀三年惦费,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了兵迅。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,133評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡薪贫,死狀恐怖恍箭,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情瞧省,我是刑警寧澤扯夭,帶...
    沈念sama閱讀 35,815評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站臀突,受9級(jí)特大地震影響勉抓,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜候学,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評(píng)論 3 331
  • 文/蒙蒙 一藕筋、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧梳码,春花似錦隐圾、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,022評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至濒蒋,卻和暖如春盐碱,著一層夾襖步出監(jiān)牢的瞬間把兔,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,147評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工瓮顽, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留县好,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,398評(píng)論 3 373
  • 正文 我出身青樓暖混,卻偏偏與公主長(zhǎng)得像缕贡,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子拣播,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容