UICollectionView與UITableView混用手勢沖突
來自: http://www.henishuo.com/collectionview-tableview-confliction/
前言
最近在重構某個模塊,以后別人封裝的所謂的基類就像一坨死一樣,看見就惡心,相信同行的你們能夠明白那種心情。為什么要重構?并不是真的因為它像一坨死,而是因為這個模塊是用戶使用最頻繁的,而且出現了不少bug,最重要的是這bug還是p1級別的致命bug。
曾經經過了幾天的壓力測試都沒有復現出來,但是用戶卻頻繁反饋,這就是決定重構的原因了。重構的界面是這樣的:
當UICollectionView中的每個cell放的是一個controller.view而這個controller.view又放一個UITableVIew時,這時候將collectionView的滾動方向設置為橫向就可以了。
但是,如果我們設置了bounces為YES,那么右滑返回手勢就沒有了,怎么辦?
實現思路
共使用了四個控制器類:
- ContentController:手勢沖突當前所在的控制器,使用UICollectionView,每個cell對應于一個控制器的view
- SiteController1:標簽一對應的控制器
- SiteController2:標簽二對應的控制器
- SiteController3:標簽三對應的控制器
配置UICollectioView
// config collection view UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc]init]; layout.itemSize = CGSizeMake(kScreenWidth, kScreenHeight - 64 - tabViewHeight); layout.scrollDirection = UICollectionViewScrollDirectionHorizontal; layout.minimumLineSpacing = 0; layout.minimumInteritemSpacing = 0; self.collectionView = [[UICollectionView alloc]initWithFrame:CGRectMake(0, 64 + tabViewHeight, kScreenWidth, kScreenHeight - 64 - tabViewHeight) collectionViewLayout:layout]; [self.viewaddSubview:self.collectionView]; self.collectionView.backgroundColor = kWColor; self.collectionView.pagingEnabled = YES; self.collectionView.showsHorizontalScrollIndicator = NO; [self.collectionViewregisterClass:[UICollectionViewCell class] forCellWithReuseIdentifier:kPatientCellIdentifier]; [self.collectionViewregisterClass:[UICollectionViewCell class] forCellWithReuseIdentifier:kUnreadCellIdentifier]; [self.collectionViewregisterClass:[UICollectionViewCell class] forCellWithReuseIdentifier:kAllCellIdentifier]; // 不能將bounces設置為NO,否則右滑返回手勢就沒有了 // self.collectionView.bounces = NO;
當我們滾動到標簽三時,再滑動就會超出范圍,此時會顯示部分空白,這體驗不太好,不希望可以再滑動了。同樣,當滑動到標簽一時,再右滑時,不希望顯示空白部分,而是觸發右滑返回手勢。
解決方案
解決方案就是實現UIScrollView的代理方法,當超出屏寬*2時,限制在屏寬*2的位置處。同樣,當小于0時,就限制在0處,這樣就解決了出現空白的問題。同時,這樣就不會關閉用戶響應,因此系統的右滑返回手勢仍然可以觸發。
經過這么一折騰,大家明白如何解決的了嗎?
#pragma mark -- UIScrollViewDelegate - (void)scrollViewDidScroll:(UIScrollView *)scrollView { // 限制不能超出屏寬*2 if (scrollView.contentOffset.x > 2 * kScreenWidth) { [scrollViewsetContentOffset:CGPointMake(2 * kScreenWidth, 0)]; return; } // 限制不能超過0 if (scrollView.contentOffset.x < 0) { [scrollViewsetContentOffset:CGPointMake(0, 0)]; return; } int itemIndex = (scrollView.contentOffset.x + self.collectionView.hdf_width* 0.5) / self.collectionView.hdf_width; itemIndex = itemIndex % [selfcollectionView:self.collectionViewnumberOfItemsInSection:0]; CGFloat x = scrollView.contentOffset.x - self.collectionView.hdf_width; NSUInteger index = fabs(x) / self.collectionView.hdf_width; CGFloat fIndex = fabs(x) / self.collectionView.hdf_width; if (fabs(fIndex - (CGFloat)index) <= 0.00001) { // ....切換按鈕 } }
最后
本篇文章沒有demo,因為這是在公司項目中所寫的,這里只是將簡單的部分總結寫出來,希望后來人可以快速填埋這個坑。
本篇文章所涉及的問題,也許與您所遇到的問題有些區別,但是希望本篇文章可以給您聯想!!!
關注我
關注 | 賬號 | 備注 |
---|---|---|
Swift/ObjC技術群一 | 324400294 | 群一若已滿,請申請群二 |
Swift/ObjC技術群二 | 494669518 | 群二若已滿,請申請群三 |
Swift/ObjC技術群三 | 461252383 | 群三若已滿,會有提示信息 |
關注微信公眾號 | iOSDevShares | 關注微信公眾號,會定期地推送好文章 |
關注新浪微博賬號 | 標哥Jacky | 關注微博,每次發布文章都會分享到新浪微博 |
關注標哥的GitHub | CoderJackyHuang | 這里有很多的Demo和開源組件 |
關于我 | 進一步了解標哥 | 如果覺得文章對您很有幫助,可捐助我! |
版權聲明:本文為【標哥的技術博客】原創出品,歡迎轉載,轉載時請注明出處!