图片轮播器是iOS开发中经常用到的一个组件,一般是采用UIScrollView来实现,但是系统的UIScrollView并不支持循环滚动,所以必须要自己手动实现。
回顾一下
在我从C++转做iOS之后,自己动手实现过一个。由于我本人只学习了不到一个月的iOS,对iOS各种组件的不熟悉,导致在工作中,我经常查找各种资料,开发App也产生了很大的阻碍。那个时候我用一种很复杂的手法实现了一个图片轮播器,虽然有好几年的时间了,但是现在回想起来还是印像很深。如今又重新实现了一次,因为知识的加深,实现起来简单了不少。
之前的实现
我之前根本不知道UIScrollView里的其他代理方法有什么用,所以整个实现我只用了一个代理方法-scrollViewDidScroll,那时候由于找不到什么资料,所以我就在考虑,到底需要多少个UIImageView呢?第一次,我是用了n+1个。确实实现了,但是转念一想,要是图片很多的时候,岂不是会很卡很慢?经过最终的考虑,确定使用三个UIImageView来实现,一个在左边,一个在中间,一个在右边。总体来说,分为以下几步
- UIScrollView开始滚动时记录conentOffset
- 实现scrollViewDidScroll记录滚动的contentOffset
- 计算两者差值,确定滚动方向
- 根据滚动方向,设置UIImageView相应的frame,使当前UIImageView处于当中
- 重新调整UIScrollView的contentOffset显示对应的UIImageView
现在的区别
可以看到,当时的实现真的是有点操蛋。现在的主要区别在于:
1. 不需要记录contentOffset
2. 不需要记录差值来确定方向
3. 不需要调整UIImageView的frame
效果展示
效果如下图所示:
代码说明
首先看对外的属性,如下所示:
这三个属性用于控制滚动的情况,
1. canScrollWhenSingle:是指只有一张图片时能否滚动
2. enableAutoScroll: 指是否允许自动滚动
3. autoScrollTimeInterval:滚动的间隔,默认5秒
再看看实现轮播器所需要的属性,
主要的属性其实就是一个UIScrollView,三个UIImageView,一个NSTimer,用于时间控制。主要代码如下所示:
我们使用一个图片数组和一个描述数组来初始化组件,在init方法中,我们设置对应的数据,启用自动滚动,设置默认滚动间隔5秒。
configure方法用于配置UI,如初始化各种View,在此就不上代码了。
然后是初始化图片,如下所示:
三个UIImageView,一个在左边,一个在中间,一个在右边,同时设置对应的图片,左边的显示最后一张图片,中间的显示第一张图片,右边的显示第二张图片。
该方法用于设置对应的属性
1. setEnableAutoScroll:如果是启用自动滚动,那么设置并启动定时器,如果是禁用自动滚动,则禁用对应的定时器。
2. setAutoScrollTimeInterval:设置滚动间隔时,如果已经启用自动滚动,那么禁用定时器,然后重新启动另一个定时器。并设置触发时间为新的滚动间隔。
滚动代理如上所示,
-scrollViewWillBeginDragging:
当开始滚动的时候,如果定时器有效,那么首先暂停定时器。
-scrollViewDidEndDecelerating:
-scrollViewDidEndScrollingAnimation:
当滚动条结束滚动的时候,这两个方法,一个用于手动拖动,一个用于代码setContentOffset,滚动结束的时候,计算对应的数据完成滚动。
如代码所示,所先计算contentOffset,即偏移量,由于开启了分页,在滚动结束的时候contentOffset的值必为0|1|2,如果是1,那么说明并没有滚动,如果是0,说明滚动向左,如果是2,说明滚动向右。然后设置当前页theCurrentPage,最后再获取对应UIImageView应该显示的图片并设置,最终,将scrollView重新设置到显示最中间的那个UIImageView,这样在用户看来是无限滚动,但其实显示的永远是中间一个,只是显示的图片不同罢了。最后再将layoutSubViews中的内容贴上来: