UICollectionView 实现整页翻动(每页3个cell)
提示:頁面架構是通過UICollectionView做的分頁,分頁點PageControl使用的是<SDCycleScrollView/TAPageControl.h> ,布局架構使用的是Masonry
前言
為了實現UICollectionView無限翻動,連續滑動,主要是利用pagingEnabled屬性,配合?UIScrollViewDelegate的代理方法來實現的。
一、準備列表數據和計算思路
1.數據源的創建(9個元素,作為數據源),目的是讓翻頁效果是3頁。
最終達到效果:
2. 思路:通過設置輪播倍數目的是通過建立多個section來實現輪播聯動在最后一次循環從頭開始排序達到循環播放。
二、使用步驟
1.初始化尺寸數據準備
代碼如下(示例):
static CGFloat const Cell_Height = 174; static CGFloat const PageDot_Height = 30;// 輪播倍數Num static const int kLoopMaxMultiple = 4; -(void)setArr_data:(NSMutableArray *)arr_data{_arr_data = arr_data;self.pageControl.numberOfPages = arr_data.count%3==0?arr_data.count/3:(arr_data.count/3+1);self.pageControl.currentPage = 0;[self.mainCV reloadData]; }2.繪畫view
代碼如下(示例):
- (void)drawView {self.backgroundColor = [UIColor clearColor];CGFloat img_w = (SCREEN_WIDTH - 15 * 4) / 3.0;[self addSubview:self.bkgView];self.bkgView.backgroundColor = [UIColor clearColor];[self.bkgView mas_makeConstraints:^(MASConstraintMaker *make) {make.left.top.right.mas_equalTo(self);make.height.mas_equalTo(Cell_Height+PageDot_Height);}];//collectionview[self.bkgView addSubview:self.mainCV];self.mainCV.delegate = self;self.mainCV.dataSource = self;[self.mainCV mas_makeConstraints:^(MASConstraintMaker *make) {make.top.mas_equalTo(self.bkgView.mas_top);make.left.mas_equalTo(self.bkgView.mas_left).mas_offset(15);make.right.mas_equalTo(self.bkgView.mas_right).mas_offset(-0);make.height.mas_equalTo(Cell_Height);}];[self.mainCV registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"cell"];[self.mainCV registerClass:[TZUploadNewPriceGoodsColCell class] forCellWithReuseIdentifier:@"TZUploadNewPriceGoodsColCell"];//pagecontrol[self.bkgView addSubview:self.pageControl];self.pageControl.frame = CGRectMake(0, Cell_Height, SCREEN_WIDTH, 30); } - (UIImage *)zd_imageWithColor:(UIColor *)colorsize:(CGSize)sizetext:(NSString *)texttextAttributes:(NSDictionary *)textAttributescircular:(BOOL)isCircular {if (!color || size.width <= 0 || size.height <= 0) return nil;CGRect rect = CGRectMake(0, 0, size.width, size.height);UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0);CGContextRef context = UIGraphicsGetCurrentContext();// circularif (isCircular) {CGPathRef path = CGPathCreateWithEllipseInRect(rect, NULL);CGContextAddPath(context, path);CGContextClip(context);CGPathRelease(path);}// colorCGContextSetFillColorWithColor(context, color.CGColor);CGContextFillRect(context, rect);// // text// CGSize textSize = [text sizeWithAttributes:textAttributes];// [text drawInRect:CGRectMake((size.width - textSize.width) / 2, (size.height - textSize.height) / 2, textSize.width, textSize.height) withAttributes:textAttributes];UIImage *image = UIGraphicsGetImageFromCurrentImageContext();UIGraphicsEndImageContext();return image; }#pragma mark - get - -(UIView *)bkgView{if(!_bkgView){_bkgView = [[UIView alloc]init];_bkgView.backgroundColor = [UIColor clearColor];_bkgView.userInteractionEnabled = YES;}return _bkgView; }-(UICollectionView *)mainCV{if(!_mainCV){CGFloat img_w = (SCREEN_WIDTH - 15 * 4) / 3.0;UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];flowLayout.itemSize = CGSizeMake(img_w, img_w*2);//管上下縫隙 minimumLineSpacingflowLayout.minimumLineSpacing = 15;//管左右縫隙 minimumInteritemSpacingflowLayout.minimumInteritemSpacing = 15;flowLayout.sectionInset = UIEdgeInsetsMake(0, 15, 0, 0);flowLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal;_mainCV = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:flowLayout];_mainCV.bounces = YES;_mainCV.pagingEnabled = YES;_mainCV.backgroundColor = [UIColor clearColor];_mainCV.showsHorizontalScrollIndicator = NO;_mainCV.showsVerticalScrollIndicator = NO;}return _mainCV; }- (TAPageControl *)pageControl {if (_pageControl == nil) {_pageControl = [[TAPageControl alloc] init];_pageControl.currentDotImage = [self zd_imageWithColor:[UIColor colorWithHexString:@"#C32136"] size:CGSizeMake(5, 5) text:@"" textAttributes:@{} circular:YES];_pageControl.dotImage = [self zd_imageWithColor:[UIColor colorWithHexString:@"#DEDEDE" alpha:1.0] size:CGSizeMake(5, 5) text:@"" textAttributes:@{} circular:YES];_pageControl.shouldResizeFromCenter = YES;}return _pageControl; }3.關鍵步驟和思路
1.獲取顯示頁面cell的index目的是為了計算頁面的頁數
/**獲取scrollView的index@param scrollView scrollView@return index*/ - (NSIndexPath* )indexWithScrollView:(UIScrollView * _Nonnull)scrollView {UICollectionView *cv = scrollView;NSArray* visibleCellIndex = cv.indexPathsForVisibleItems;NSArray *sortedIndexPaths = [visibleCellIndex sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {NSIndexPath *path1 = (NSIndexPath *)obj1;NSIndexPath *path2 = (NSIndexPath *)obj2;return [path1 compare:path2];}];NSIndexPath* indexPath = [sortedIndexPaths firstObject];return indexPath; }2.滾動到相應的頁數collectionview和Pagecontrol聯動
/**滾動到指定索引@param scrollView scrollView*/ - (void)scrollToIndex:(UIScrollView *)scrollView {NSIndexPath* index = [self indexWithScrollView:scrollView];NSInteger item_section = index.section;if (index.section == kLoopMaxMultiple - 1) {item_section = 0;}NSIndexPath *indexPath = [NSIndexPath indexPathForItem: index.row inSection:item_section];[self.mainCV scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionLeft animated:NO];self.pageControl.currentPage = index.row/3;}3.UICollectionView代理方法(將分格空間做在cell 里面,不然整頁翻動會有偏移偏移的量為分隔空間的倍數),將數據賦值多份通過多個section來實現第一次最后一幀能夠與第一幀接上
#pragma mark-- 數據 --- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {return kLoopMaxMultiple; } - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {return self.arr_data.count; }- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {TZUploadNewPriceGoodsColCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"TZUploadNewPriceGoodsColCell" forIndexPath:indexPath];cell.titL.text = [NSString stringWithFormat:@"題目:第%ld頁 -- row:%ld -- section:%ld",indexPath.row/3+1,indexPath.row,indexPath.section];return cell; }- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {}- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {CGFloat img_w = (SCREEN_WIDTH - 15 * 4) / 3.0;return CGSizeMake(floor(img_w)+15, Cell_Height); }- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {return UIEdgeInsetsMake(0, 0, 0, 0); } - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section {return 0.000001; } - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section {return 0.000001; }// 設置區頭尺寸高度 - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section {CGSize size = CGSizeMake(0.00001, 0.00001);return size; }// 設置區尾尺寸高度 - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section {return CGSizeMake(0.00001, 0.00001); }?4.UIScrollViewDelegate代理方法
scrollViewDidEndScrollingAnimation?不是人為滾動的方法
scrollViewDidEndDecelerating 是人為滑動的方法
總結
通過UICollectionView的屬性@property (nonatomic, readonly) NSArray<NSIndexPath *> *indexPathsForVisibleItems;來獲取當前頁面上顯示的cell再排序(**排序很重要)
當當前cell的index.section == kLoopMaxMultiple - 1 是最后一個分區的時候一定要去滾動到第一個分區從新開始?? ? [self.mainCV scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionLeft animated:NO]; (動畫要關了)
UIScrollViewDelegate的代理一定要區分停止滾動的類型(人為拖拽scrollViewDidEndDecelerating、和代碼自動滾動scrollViewDidEndScrollingAnimation)
總結
以上是生活随笔為你收集整理的UICollectionView 实现整页翻动(每页3个cell)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 村村通(并查集)
- 下一篇: Antd a-menu 样式修改