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 *)color
                          size:(CGSize)size
                          text:(NSString *)text
                textAttributes:(NSDictionary *)textAttributes
                      circular:(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();
    // circular
    if (isCircular) {
        CGPathRef path = CGPathCreateWithEllipseInRect(rect, NULL);
        CGContextAddPath(context, path);
        CGContextClip(context);
        CGPathRelease(path);
    }
    // color
    CGContextSetFillColorWithColor(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);

        //管上下缝隙 minimumLineSpacing
        flowLayout.minimumLineSpacing = 15;
        //管左右缝隙 minimumInteritemSpacing
        flowLayout.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代理方法

  1. scrollViewDidEndScrollingAnimation 不是人为滚动的方法

  2. scrollViewDidEndDecelerating 是人为滑动的方法

#pragma mark - UIScrollViewDelegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    NSIndexPath *indexP = [self indexWithScrollView:scrollView];
    NSInteger index = indexP.row/3;
    self.pageControl.currentPage = index;
}

//不是人为滚动
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView {
    [self scrollToIndex:scrollView];
}

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
    
}
//是人为滚动
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    [self scrollToIndex:scrollView];
}


总结

  1. 通过UICollectionView的属性@property (nonatomic, readonly) NSArray<NSIndexPath *> *indexPathsForVisibleItems;来获取当前页面上显示的cell再排序(**排序很重要)

  2. 当当前cell的index.section == kLoopMaxMultiple - 1 是最后一个分区的时候一定要去滚动到第一个分区从新开始     [self.mainCV scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionLeft animated:NO]; (动画要关了)

  3. UIScrollViewDelegate的代理一定要区分停止滚动的类型(人为拖拽scrollViewDidEndDecelerating、和代码自动滚动scrollViewDidEndScrollingAnimation

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/18075.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2023年计算机视觉与模式识别国际会议(CCVPR 2023)

会议简介 Brief Introduction 2023年计算机视觉与模式识别国际会议(CCVPR 2023) 会议时间&#xff1a;2023年9月15日-17日 召开地点&#xff1a;英国牛津 大会官网&#xff1a;www.ccvpr.org 计算机视觉技术与模式识别是现代科学中备受关注的热点技术&#xff0c;它的革新对各行…

改写句子的软件有哪些-免费改写文章的软件

改写句子的软件 改写句子的软件是一种广泛应用于文字处理的工具&#xff0c;其主要作用是通过对原文中的语言结构和表述方式进行调整和优化&#xff0c;以改进文章的质量和可读性。改写句子的软件广泛用于新闻报道、科学文章、学术论文、书籍等各类文本材料中&#xff0c;旨在…

港科夜闻|广东省委常委、副省长王曦到访香港科技大学

关注并星标 每周阅读港科夜闻 建立新视野 开启新思维 1、广东省委常委、副省长王曦到访香港科技大学。在香港科大校长、粤港澳大湾区院士联盟理事会主席叶玉如教授陪同下&#xff0c;王曦常委率代表团参观国家级科研设施和了解学校发展情况&#xff0c;并与在港中国科学院院士座…

分享kubernetes部署:cachecloud部署说明

cachecloud部署 cachecloud是搜狐视频(sohutv)Redis私有云平台 已省略~ 挑选一台服务器部署cachecloud-web 将cachecloud-web打成war包&#xff0c;可以在服务器上打包&#xff0c;也可以在本地打包&#xff0c;这里举一个在服务器上打包的例子。 将源代码下载到/opt下 已省略~…

使用 SaleSmartly 实时聊天提高转化率

在竞争激烈的电子商务环境中&#xff0c;很难给客户留下持久的印象&#xff0c;与他们建立关系更加困难。但是&#xff0c;提供个性化的体验和产品是超越竞争对手的最佳方式之一。这就是为什么许多跨境电子商务企业将与客户的个性化沟通作为他们的首要任务。 SaleSmartly&#…

【Java数据结构】优先级队列(堆)

优先级队列&#xff08;堆&#xff09; 概念模拟实现堆的概念堆的存储方式堆的创建向下调整堆的创建建堆的时间复杂度 堆的插入和删除堆的插入堆的删除 用堆模拟实现优先级队列 常用接口PriorityQueue的特性PriorityQueue常用接口介绍构造方法插入/删除/获取优先级最高的元素 P…

Lecture 14:Life-long Learning

目录 Catastrophic Forgetting 灾难性遗忘(Catastrophic Forgetting)的克服之道 Selective Synaptic Plasticity Additional Neural Resource Allocation Memory Reply 其他 Catastrophic Forgetting ——为什么今日的人工智慧无法成为天网&#xff1f;灾难性遗忘 Life…

2-Lampiao百个靶机渗透(精写-思路为主)框架漏洞利用2

特别注明&#xff1a;本文章只用于学习交流&#xff0c;不可用来从事违法犯罪活动&#xff0c;如使用者用来从事违法犯罪行为&#xff0c;一切与作者无关。 文章目录 前言一、环境重新部署二、AWVSxray联动和xraybs联动1.安装AWVSxray2.让xray和bs先联动3.AWVS和xray联动 三、p…

Camtasia2023官方中文版免费下载

在现在的网络互联网时代&#xff0c;越来越多的人走上了自媒体的道路。有些自媒体人会自己在网络上录制精彩视频&#xff0c;也有一些人会将精彩、热门的电影剪辑出来再加上自己给它的配音&#xff0c;做成大家喜欢看的电影剪辑片段。相信不管大家是自己平时有独特的爱好也好、…

欧科云链OKLink:2023年4月安全事件盘点

一、基本信息 2023年4月安全事件共造约6000万美金的损失&#xff0c;与上个月相比&#xff0c;损失金额有所降落&#xff0c;但安全事件数量依旧不减。其中&#xff0c;Yearn Finance因参数配置错误&#xff0c;导致了1000多万美金的损失。同时&#xff0c;有一些已经出现过的…

ZC706P试验PL_DDR3内存条的步骤方法

ZC706P 板卡完全兼容XILINX官方的ZC706,当然也支持PL外挂的1G的DDR3内存条&#xff0c;这个片BLOG我提供从官方下载的一个文档和一个项目&#xff0c;演示一下验证DDR3的步骤。 步骤1&#xff1a;准备好板子&#xff0c;安装好软件。 链接&#xff1a;https://pan.baidu.com/s…

JVM原理与实战(一)

jvm的基本结构 1.类加载系统 负责从文件系统或者网络中加载Class信息 2.方法区 &#xff08;1&#xff09;加载的类信息存放于一块称为方法去的内存空间 &#xff08;2&#xff09;除了类的信息外&#xff0c;方法区中可能还存放着运行时常量池信息&#xff0c;包括字符串字面…

什么是皮安计?皮安表测试测量软件分享NS-SourceMeter

什么是皮安计 测量低直流电流&#xff0c;其需求常常远远超出数字万用表的功能。一般来说&#xff0c;数字万用表缺少测量低于100nA的电流所需的灵敏度。即使在较高的电流水平上&#xff0c;一个DMM的输入电压降&#xff08;电压负担&#xff09;高达几百毫伏&#xff0c;也不…

DD驱动鼠标键盘(驱动级别机器人使用鼠标键盘)

官网下载 DD虚拟键盘虚拟鼠标 github下载 GitHub - ddxoft/master 点击下载后&#xff0c;将驱动包下&#xff0c;这里以win7为例 setup运行安装 安装成功后 可以打开电脑管理&#xff0c;可以看见DD虚拟鼠标和键盘 这里以JAVA接入为例 使用管理员权限启动eclipse &#…

汇编语言-复习自用

本文用于自我复习汇编语言&#xff0c;参考b站一位老师的讲解整理而成&#xff0c;感谢老师的无私付出视频链接链接 文章目录 1.第一章1.1计算机组成1.2读取1.3 寄存器及数据存储1.4 mov和and指令1.5 确定物理地址1.6 内存分段表示法1.7debug使用1.8CS:IP1.9jmp指令改变csip1.1…

【react 全家桶】高级指引(上)

本人大二学生一枚&#xff0c;热爱前端&#xff0c;欢迎来交流学习哦&#xff0c;一起来学习吧。 <专栏推荐> &#x1f525;&#xff1a;js专栏 &#x1f525;&#xff1a;vue专栏 &#x1f525;&#xff1a;react专栏 文章目录 12 【react高级指引&#xff08;上&…

SSM框架(SpringBoot快速构建)

简介 本文意在快速构建一个可以接受前端访问&#xff0c;并进行数据库查找&#xff0c;随后返回相关信息给前端的项目。 ssm为Spring IocSpringMVCMyBatis的缩写 Spring Ioc:管理对象的一个工厂。对象之间有依赖&#xff0c;相互引用Spring MVC:开发代码模式Mybatis:操作数据…

7万字省级智慧农业大数据平台项目规划建设方案

1.1 系统总体结构和逻辑结构 XX市智慧农业项目数据中心是全省数据处理加工和数据分析应用的中心&#xff0c;总体上需实现上连省农业厅、下连各级农业、外连市级部门&#xff1b;构建资源整合、互联互通、资源共享的全省统一的数据中心资源库&#xff1b;构建完善的底层支撑平…

放弃40k月薪的程序员工作,选择公务员,我来分享一下看法

我有一个朋友&#xff0c;拒绝了我为他提供的4万薪水的工作&#xff0c;去了一个体制内的银行&#xff0c;做程序员&#xff0c;即使薪水减半。他之前在北京一家大公司做程序员&#xff0c;一个月30k。当我开始创业时&#xff0c;我拉他来和我一起干&#xff0c;但那时我们太小…

windeployqt工具打包C++ QT项目

目录 前言方法TIP 前言 使用VS编写好QT项目后&#xff0c;有时需要发送给他人进行测试。在此情况下&#xff0c;发送所有项目文件显然不可取&#xff0c;因为exe文件不能独立运行&#xff0c;故在测试前需要先配置项目环境&#xff0c;以确保运行所需的库文件能够完全。 因此&…
最新文章