2019独角兽企业重金招聘Python工程师标准>>>

1 使用UIScrollview实现无限轮播原理

  在开发中常需要对广告或者是一些图片进行自动的轮播,也就是所谓的无限滚动。

  在开发的时候,我们通常的做法是使用一个UIScrollView,在UIScrollView上面添加多个imageView,然后设置imageView的图片,和scrollView的滚动范围。

  以前的做法:

  

  一般而言,轮播的广告或者是图片数量都不会太多(3~5张)。所以,并不会太多的去考虑性能问题。但是如果图片过多(比如有16张图片,就需要创建16个imageView),那么就不得不考虑性能问题了。

  更甚,如果深入做一个图片浏览的小程序,那么可能会处理成百上千张图片,这会造成极大的内存浪费且性能低下。

  图片数量众多:

  

当用户在查看第一张图片的时候,后面的7张创建的时间太早,且用户可能根本就没机会看见(看完前面几张就没有兴趣再看后面的内容 了)。

优化思路:只有在需要用到的时候,再创建,创建的imageView进行村循环利用。比较好的做法,不论有多少张图片,只需要创建3个imageView就够了。

  
使用UIScrollView来实现,首先设置三个固定的UIImageView(下文分别用L、M、R代替)放入一个UIScrollview中,M总是显示当前要显示的图片,而L和R根据M的变化而变化。

当然,还需要一个依次存储图片信息数据的数组(以下简称array),用于给L、M、R三张试图提供数据源。

举例

循环轮播0,1,2,3 这四张图片,当M显示第0张时,将4赋给L,将2赋给R。

初始状态

  • 将试图向左滑动后,屏幕上显示的是R,即显示的是图片1。

则在此时,在后台将M的图片设置为1,将UIScrollview的偏移量设置成初始状态。接着将L设置为0,R设置为2。这里的UIImageView的image变化和UIScrollView偏移量设置都不能开始UIView的动画效果。最终的现实效果如下图:

  • 向右滑动和向左滑动是一样的道理,当然遇到array头和尾时是需要处理的,使用模运算符(%)就可以了:

    L取得图片是(index+ array.count)%array.count,
    RM取得图片的索引是(index+ array.count -1)%array.count,
    R取得图片是(index+ array.count + 1)%array.count,

2 使用CollectionView实现无限轮播的具体实现

本文介绍使用Collectionview来实现无限滚动的循环利用。它支持垂直和水平方向上的滚动。

今天为什么写这个呢,之前写过项目用scrollView封装写过轮播图,但是感觉不是很好,而且传值也很不好写,所以今天用collectionView写的轮播图,传值也很是好写的。

5517BA7A-0DE8-43B6-8C97-7BACA687416D.png

<1>先定一些我们需要的属性

@property (nonatomic, retain) UICollectionView *collection;
@property (nonatomic, retain) NSMutableArray *marr;// 存图片的数组
@property (nonatomic, retain) UIPageControl *page;
@property (nonatomic, retain) NSTimer *timer;
// 调用的一些方法
- (void)viewDidLoad {[super viewDidLoad];[self createCollectionView];[self createPhone];[self createPage];[self addTimer];// Do any additional setup after loading the view, typically from a nib.
}

<2>//先做一些事前工作,把collectionView铺好

    UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc]init];layout.itemSize = CGSizeMake(WIDTH, 300);layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;layout.minimumLineSpacing = 0;self.collection = [[UICollectionView alloc]initWithFrame:CGRectMake(0, 0, WIDTH, 300) collectionViewLayout:layout];[self.view addSubview:self.collection];self.collection.backgroundColor = [UIColor whiteColor];self.collection.pagingEnabled = YES;//开启翻页效果self.collection.delegate = self;self.collection.dataSource = self;self.collection.showsHorizontalScrollIndicator = NO;//滑条不出现[self.collection registerClass:[CellOfFirst class] forCellWithReuseIdentifier:@"pool"];

<3>collectionView 的协议方法

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {return self.marr.count;// 返回图片的个数
}
// 说一下为什么返回100个分区
// 我们可以将第50个分区的一组图片作为用户看到的第一组图片,这样就实现轮播的效果了。(100分区足够了,除非脑残划100次)
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {return 100;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
// 自定义的Cell类CellOfFirst *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"pool" forIndexPath:indexPath];cell.pic.image = self.marr[indexPath.row];return cell;}

// 本地的图片

- (void)createPhone {self.marr = [NSMutableArray array];for (int i = 1; i < 12; i++) {NSString *name = [NSString stringWithFormat:@"123_%d.jpg",i];UIImage *image = [UIImage imageNamed:name];[self.marr addObject:image];}//设置起始位置[self.collection scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:50] atScrollPosition:UICollectionViewScrollPositionLeft animated:NO];
}

// 获取pageControoler

// 被忘记调用呦
- (void)createPage {self.page = [[UIPageControl alloc]initWithFrame:CGRectMake(0, 250, WIDTH, 50)];[self.view addSubview:self.page];self.page.numberOfPages = self.marr.count;}

// 当图片划得时候已经减速时

// collectionView继承于scrollview 所以我们可用此方法
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {// 计算page算法int page = (int) (scrollView.contentOffset.x / WIDTH + 0.5) % self.marr.count;self.page.currentPage = page;}

// 我们可以添加定时器了 (一样别忘记获取完图片调用)

- (void)addTimer {self.timer = [NSTimer scheduledTimerWithTimeInterval:3.0 target:self selector:@selector(nextImage) userInfo:nil repeats:YES];[[NSRunLoop mainRunLoop] addTimer:_timer forMode:NSRunLoopCommonModes];
}
- (void)nextImage {//设置当前 indePathNSIndexPath *currrentIndexPath = [[self.collection indexPathsForVisibleItems]lastObject];NSIndexPath *currentIndexPathReset = [NSIndexPath indexPathForItem:currrentIndexPath.item inSection:50];[self.collection scrollToItemAtIndexPath:currentIndexPathReset atScrollPosition:UICollectionViewScrollPositionLeft animated:NO];// 设置下一个滚动的itemNSInteger nextItem = currentIndexPathReset.item +1;NSInteger nextSection = currentIndexPathReset.section;if (nextItem==self.marr.count) {// 当item等于轮播图的总个数的时候// item等于0, 分区加1// 未达到的时候永远在50分区中nextItem=0;nextSection++;}NSIndexPath *nextIndexPath = [NSIndexPath indexPathForItem:nextItem inSection:nextSection];[self.collection scrollToItemAtIndexPath:nextIndexPath atScrollPosition:UICollectionViewScrollPositionLeft animated:YES];
}

// 当用户自己划图片时 当然我们也需要定时器被移除 (时机很重要)

- (void)removeTimer{[self.timer invalidate];self.timer = nil;}

// 当图片即将开始被拖拽时 我们将定时器移除

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {[self removeTimer];
}

// 当图片已经完成被拖拽时 我们还需加上定时器

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {[self addTimer];
}

这些做完我们基本就完成轮播图自动轮播了,大家有兴趣的可以尝试下。

转载于:https://my.oschina.net/u/2524932/blog/733184

iOS无限轮播图片的两种方式相关推荐

  1. JavaScript+HTML+CSS 无缝滚动轮播图的两种方式

    第一种方式 在轮播图最后添加第一张,一张重复的图片. 点击前一张,到了第一张,将父级oList移动到最后一张(也就是添加的重复的第一张),在进行后续动画. 点击下一张,到了最后一张(也就是添加的重复的 ...

  2. 设置背景图片的两种方式,并解决手机端背景图片高度自适应问题

    设置背景图片的两种方式,并解决手机端背景图片高度自适应问题 参考文章: (1)设置背景图片的两种方式,并解决手机端背景图片高度自适应问题 (2)https://www.cnblogs.com/Dark ...

  3. ImGui添加背景图片的两种方式

    给ImGui添加背景图片的两种方式 最近在使用ImGui做客户端程序,想给窗口添加背景图片,但是作者的文档里面好像并没有讲如何添加背景图片,研究了下找到了两种方式. 第一种 创建一个和窗口一样大的Im ...

  4. Android加载GIF图片的两种方式

    飞哥语录:得到一件东西最好的方式是让自己配得上它. 方式一:使用第三开源框架直接在布局文件中加载gif 1.在工程的build.gradle中添加如下 buildscript {repositorie ...

  5. 无限轮播图片的实现原理

    无限轮播图相信是很多开发人员常用的一个功能,这里总结一下常用的两种方式的实现原理 一.使用UIScrollview实现无限轮播 用UIScrollView实现,在scrollView上添加3个UIIm ...

  6. 轮播图的两种方法及自动轮播

    轮播图共计四种方法,本期先向大家分享两种,下期会补充剩余二个方法 公共部分: * {padding: 0px;margin: 0px;}.banner {width: 600px;margin: au ...

  7. Android之从网络上获取图片的两种方式讲解:thread+handle和AsyncTask方式

    从网络上获取图片是一个比较耗时的操作,放在主线程会导致阻塞主线程,响应超时,所以我们不能把它放在主线程里操作,必须放在一个子线程里,我打算采用两种方式去实现.1.采用thread去获取图片,获取到后通 ...

  8. iOS WKWebView和JS交互的两种方式

    2019独角兽企业重金招聘Python工程师标准>>> 本文介绍两种方式实现iOS WKWebView和JS交互 WKWebViewConfiguration注入WKScriptMe ...

  9. iOS开发中拉伸图片的几种方式

    在iOS开发中,经常会遇到控件尺寸和图片大小不匹配的情况. 一些情况下, 我们需要对图片进行拉伸, 以满足美观需求. 总的来说, 图片的拉伸方式可以分为两种, 一种是通过Xcode自带的Show Sl ...

最新文章

  1. -static 静态链接库的某些问题
  2. 洛谷模拟赛 数据结构
  3. 绿色数据中心将惠及众生
  4. 怎么查看ftp服务器的版本信息,查看ftp服务器版本
  5. Hyperledger Fabric 排序服务核心原理和工作过程
  6. 剑指offer(17)树的子结构
  7. python爬虫开发环境中几个爬虫库的主要用途_分分钟了解Python爬虫
  8. java高级程序员如何写好简历,一份优秀的程序员简历是什么样的?
  9. FastAPI基础:Depends怎么用?
  10. doe五步法_DOE方法介绍
  11. python操作cad的模块_Process Autocad by python
  12. video-js rtmp直播、this .el_vjs_getproperty问题、多个rtmp播放、可用rtmp地址
  13. 10分钟搞定图形图像识别
  14. OpenCV-Python教程
  15. 腾讯云网站备案咨询:网站信息类问题汇总解答
  16. “逃犯克星”张学友演唱会完成八杀,幕后功臣竟然是它
  17. 行业调研:Platform Ops
  18. 如何将前端代码写的优雅?
  19. 产销存报表直接在MB5B上取数
  20. 中国智慧生活博览会(CEE 2017)—数字世界亚洲博览会会刊(参展商名录)

热门文章

  1. npm报错,安装不上依赖,npm代理报错
  2. 怎么终止linux的次序运行程序,linux – 如何按特定顺序停止systemd服务
  3. mysql的槽_Mysql槽点 - MySQL及其它开源数据库 - ITPUB论坛-中国专业的IT技术社区...
  4. 环境在c盘_程序员,拯救我的C盘
  5. 登录超时服务器未响应,怎样解决超时时间已到、在操作完成之前超时时间已过或服务器未响应的问题?...
  6. jfinal 源码中文乱码解决
  7. DeskClock选择闹钟声音时有重复选项
  8. vb 字符串转为数字 和判断字符串是否是数字字符串【转】
  9. 马斯克新梦想迈出第一步!首条地下高速隧道即将完工,12月免费体验
  10. 微软又开源了一个机器学习框架,这次是核心产品的机器学习引擎infer.NET