当前位置: 首页 > news >正文

iOS项目练习: 无限自动轮播视图和pageControl的联动

文章目录无限自动轮播视图和pageControl的联动scrollView 的添加与配置pageControl 的添加与配置pageControl 变化时更新 scrollViewscrollView 滑动时更新 pageControl定时器的设置与停止用户滑动时停止定时器结束后重新开启无动画跳转实现无限循环无限自动轮播视图和pageControl的联动目前为止, 在zara和share的项目中都用到了无限轮播视图和pageControl的结合, 通过定时器来控制视图自动切换,同时还要是pageControl跟随scrollView同步更新, 这就需要用到scrollView的代理在练习zara和share的时候, 遇到实现无线轮播视图和pageControl的时候都遇到了困难, 例如scrollView的偏移量(scrollView.contentOffset). pageControl 的索引的设置, 在滑动scrollView的时候要停止stop, 滑动完成之后再开启定时器 等, 解决这些困难的时候都花费了很多时间, 下面将这一知识点做一总结和整理scrollView 的添加与配置首先创建UIScrolView并将其添加到视图-(void)setScrollView{self.scrollView[[UIScrollView alloc]init];// 按页翻动self.scrollView.pagingEnabledYES;// 允许滑动self.scrollView.scrollEnabledYES;[self.contentView addSubview:self.scrollView];[self.scrollView mas_makeConstraints:^(MASConstraintMaker*make){make.edges.mas_equalTo(self.contentView);}];self.scrollView.delegateself;}然后需要设置画布(scrollView.contentView)的大小因为Masonry在设置完约束之后,是没有立即生效的, 所以此时的 scrollView的宽和高都是 0 , 要使用scrollView 的width 和 height 来设置画布的大小,需要使用[self.scrollView layoutIfNeeded];方法来强制属性布局,来使约束强制生效在添加视图的时候,我们需要实现无限轮播的效果, 就需要在添加轮播视图的图片数组中添加临时界面,在开头插入一张要展示的界面的最后一张图片, 在末尾插入一张要展示的第一张图片, 之后在滑动到开头的临时界面的时候我们可以直接跳转到最后一张要展示的界面, 当滑动到默认的临时界面的时候直接跳转到第一张要展示的界面的, 这样在视觉效果上就实现了无限轮播然后接可以向滚动视图中添加视图了, 注意这里的视图添加的时候需要计算好偏移量, 一般是每个视图的宽度设置为scrollView的width, 然后是每个视图在添加的时候, x坐标就偏移几个scrollView.width-(void)configureData:(NSMutableArray*)images{// 设置总页数self.pageControl.numberOfPagesimages.count-2;self.scrollView.contentSizeCGSizeMake(self.contentView.bounds.size.width*images.count,self.contentView.bounds.size.height);self.scrollView.contentOffsetCGPointMake(self.contentView.bounds.size.width,0);for(inti0;iimages.count;i){UIImage*imageimages[i];UIImageView*iView[[UIImageView alloc]initWithImage:image];iView.contentModeUIViewContentModeScaleAspectFill;iView.clipsToBoundsYES;[self.scrollView addSubview:iView];[iView mas_makeConstraints:^(MASConstraintMaker*make){make.left.mas_equalTo(self.scrollView).offset(self.contentView.bounds.size.width*i);make.top.mas_equalTo(self.scrollView);make.width.height.mas_equalTo(self.contentView);}];}}在添加imageView的时候, 我设置了图片等比填充和裁剪边缘超出部分,这样就会使图片不会被拉伸变形iView.contentModeUIViewContentModeScaleAspectFill;iView.clipsToBoundsYES;pageControl 的添加与配置pageControl 用于显示当前轮播图所在的页码需要注意的是numberOfPages要设置为图片数组去掉首尾两张临时图片之后的真实数量-(void)setpageControl{self.pageControl[[UIPageControl alloc]init];self.pageControl.currentPageIndicatorTintColor[UIColor redColor];self.pageControl.pageIndicatorTintColor[UIColor grayColor];// 当只有一页时隐藏 pageControlself.pageControl.hidesForSinglePageYES;[self.contentView addSubview:self.pageControl];[self.pageControl mas_makeConstraints:^(MASConstraintMaker*make){make.centerX.mas_equalTo(self.contentView);make.bottom.mas_equalTo(self.contentView).offset(-10);make.height.mas_equalTo(30);make.width.mas_equalTo(200);}];self.pageControl.currentPage0;// 监听 pageControl 点击事件[self.pageControl addTarget:selfaction:selector(pageChange)forControlEvents:UIControlEventValueChanged];}在configureData:中设置真实页数去掉首尾两张临时图片为什么说不在创建的时候直接设置总页数呢, 是因为在我们创建pageControl的时候,homeModel还没有接收外部传入的值, 此时self.homeModel为nil, homeModel.scrollViewImages.count 为 0self.pageControl.numberOfPagesimages.count-2;pageControl 变化时更新 scrollView当用户点击 pageControl 切换页码时需要同步更新 scrollView 的偏移量。注意 scrollView 中 index 为 0 的位置是临时图片所以真实第一张图片的偏移量是scrollView.bounds.size.width * 1因此需要对 pageControl 的 index 加 1 来计算出正确的偏移量-(void)pageChange{[selfstopTimer];NSInteger indexself.pageControl.currentPage;[self.scrollView setContentOffset:CGPointMake(self.scrollView.bounds.size.width*(index1),0)animated:YES];[selfsetTimer];}scrollView 滑动时更新 pageControlscrollView 在滑动过程中需要实时更新 pageControl 的当前页码这里通过scrollViewDidScroll:代理方法来实现首先需要一个计算当前页码的方法通过当前偏移量除以单页宽度来获取加上0.5 * width是为了让翻页时机在滑过一半时触发视觉效果更自然-(CGFloat)currentPage{NSInteger page(self.scrollView.contentOffset.x0.5*self.scrollView.bounds.size.width)/self.contentView.bounds.size.width;returnpage;}然后在scrollViewDidScroll:中更新 pageControl注意 scrollView 中的 page 比 pageControl 的 index 多 1因为开头有一张临时图片所以要减 1。另外还需要处理边界情况当滑动到临时图片区域时pageControl 要显示对应的真实页码-(void)scrollViewDidScroll:(UIScrollView*)scrollView{NSInteger page[selfcurrentPage]-1;// 滑动到末尾的临时图片时pageControl 显示第 0 页if(pageself.homeModel.scrollImages.count-2){page0;// 滑动到开头的临时图片时pageControl 显示最后一页}elseif(page-1){pageself.pageControl.numberOfPages-1;}self.pageControl.currentPagepage;}定时器的设置与停止定时器用于控制轮播图自动翻页每隔一定时间触发一次nextPage方法。在创建定时器之前先判断是否已经存在避免重复创建导致翻页速度异常-(void)setTimer{if(self.timernil){self.timer[NSTimer scheduledTimerWithTimeInterval:3target:selfselector:selector(nextPage)userInfo:nil repeats:YES];}}-(void)stopTimer{[self.timer invalidate];self.timernil;}nextPage方法负责计算下一页的偏移量并滚动到对应位置不需要手动修改 pageControl因为scrollViewDidScroll:会自动同步。这里直接让 scrollView 往后滚动一页当滚动到末尾临时图片时由scrollViewDidEndScrollingAnimation:无动画跳回真实的第一张-(void)nextPage{NSInteger pageself.pageControl.currentPage1;// 不重置 page让 scrollView 继续往后滚动到末尾临时图片// scrollViewDidEndScrollingAnimation 会处理无动画跳回逻辑[self.scrollView setContentOffset:CGPointMake(self.scrollView.bounds.size.width*(page1),0)animated:YES];}用户滑动时停止定时器结束后重新开启用户手动滑动时需要停止定时器避免自动翻页和手动滑动冲突。通过scrollViewWillBeginDragging:在用户开始滑动时停止定时器通过scrollViewDidEndDecelerating:在滑动结束减速完成后重新开启// 用户开始滑动时停止定时器-(void)scrollViewWillBeginDragging:(UIScrollView*)scrollView{[selfstopTimer];}// 用户滑动结束减速完成后重新开启定时器-(void)scrollViewDidEndDecelerating:(UIScrollView*)scrollView{NSInteger page[selfcurrentPage];if(page0){[scrollView setContentOffset:CGPointMake(self.scrollView.bounds.size.width*(self.homeModel.scrollImages.count-2),0)animated:NO];}elseif(pageself.homeModel.scrollImages.count-1){[scrollView setContentOffset:CGPointMake(self.scrollView.bounds.size.width*1,0)animated:NO];}[selfsetTimer];}无动画跳转实现无限循环当代码触发的动画滚动结束时scrollViewDidEndScrollingAnimation:需要判断当前是否滚到了临时图片的位置如果是则无动画直接跳转到对应的真实图片由于没有动画用户感知不到跳转视觉上就实现了无限循环-(void)scrollViewDidEndScrollingAnimation:(UIScrollView*)scrollView{NSInteger page[selfcurrentPage];// 滚到了开头的临时图片无动画跳转到真实的最后一张if(page0){[scrollView setContentOffset:CGPointMake(self.scrollView.bounds.size.width*(self.homeModel.scrollImages.count-2),0)animated:NO];// 滚到了末尾的临时图片无动画跳转到真实的第一张}elseif(pageself.homeModel.scrollImages.count-1){[scrollView setContentOffset:CGPointMake(self.scrollView.bounds.size.width*1,0)animated:NO];}}下面用展示设置动画的前后效果对比设置有动画设置无动画可以看到, 在设置有动画就会导致到达临时页的时候有一个向前翻页的动画, 而关闭动画之后就直接跳转,显得更加顺畅
http://www.zskr.cn/news/1374975.html

相关文章:

  • DBSCAN与GMM串联:从盖亚天文大数据中自动发现恒星关联结构
  • 算法公平性约束下的最优决策:PPV与FOR平等如何重塑决策规则
  • ML赋能BDI智能体:规划、意图过滤与行动模块的技术融合与实践
  • 基于TorchGeo的遥感影像深度学习实战:从Sentinel-2到作物分类
  • 初创公司如何通过Taotoken的Token Plan套餐有效控制AI实验成本
  • 终极指南:5分钟快速上手科学机器学习库DeepXDE
  • 从Voronoi图到Lloyd算法:分布式传感器网络收敛性证明与工程实践
  • FT2232芯片通过JTAG连接Xilinx FPGA
  • m4s-converter深度解析:3步高效解决B站m4s文件转MP4的完整技术方案
  • 已经能获取到从apache2获取的客户端的IP地址
  • Kubernetes CronJob 速查手册:核心语法与实战示例
  • 最新热门个人AI编程工具全盘点,独立开发者副业开发首选AI编程助手
  • 告别刻录盘!用Rufus 4.5把旧U盘秒变Win10安装神器(保姆级图文)
  • Alpine Linux的apk包管理器,除了安装软件还能做什么?(5个隐藏用法解析)
  • Linux运维排查:当进程卡死时,用ipcs命令快速定位信号量或共享内存问题
  • 我是KKKKKKK
  • 手把手教你CentOS7升级gcc和make,为glibc升级铺平道路(含依赖检查清单)
  • 基于随机森林的H I 21厘米吸收线自动分类:从谱线拟合到天体物理洞察
  • 新手学java多态的感受
  • 构建负责任AI日志框架:从公平性、可解释性到合规审计的工程实践
  • 数字图像处理-7-图像的梯度锐化算法
  • 2026年比较好的洗衣机碳刷/南通风扇碳刷/跑步机碳刷/汽车起动机碳刷厂家哪家好 - 行业平台推荐
  • AlphaEvolve:LLM与进化算法融合的自动代码优化系统
  • 告别臃肿!用终端命令一键清理macOS Sonoma里不用的4K动态壁纸
  • ARM SME多向量浮点运算指令FAMAX/FAMIN详解
  • 全波形反演新思路:大步长梯度优化器如何克服周波跳跃难题
  • 后端开发与DevOps的融合:持续集成与部署实战
  • 为什么你的ChatGPT公众号打开率不足8%?腾讯内部流出的3类高唤醒标题公式(限时公开)
  • CryENGINE三层架构实战:C++/C#/Lua协同开发与安全绑定
  • 【论文阅读】VLAW: Iterative Co-Improvement of Vision-Language-Action Policy and World Model