一组图片循环滑动在开发中经常用到,App的欢迎页、广告banner等等都会用到。成熟的第三方也比较多,个人用的比较多的是JCTopic,这个很轻量级,代码也不多,用起来也是比较方便。
看过源码之后整理了一下实现的思路和原理,我们先来分析一下我们要实现的这个功能——图片循环轮播,看到这个需求我们想到的就是一组图片能够左右滑动,并且无限循环。
要实现这个功能,我们肯定需要一个可滑动的view,那么这个时候我们可以选择UIScrollView、UITableView、UICollectionView,UITableView竖向的也可以实现,不过如果用UITableView的话选择UICollectionView会更好一些,因为两者实现原理一样的,但是竖向UITableView不常用。
那么剩下的UIScrollView和UICollectionView怎么选呢?个人觉得数量比较少的图片直接用UIScrollView就可以了,UIScrollView用起来简单方便,如果图片特别多的话那就用UICollectionView,因为这个时候需要复用,避免内存消耗过大。
JCTopic就是封装了一个继承UIScrollView的类,但是个人觉得他这个还是有待优化的,这里我先讲实现原理,后面我会重新封装一个类似于JCTopic的类,会把这个代码进行优化。
优化后的代码地址:https://download.csdn.net/download/aaaaazq/10628355
我们先来看一下UIScrollView在实现图片循环轮播时的一个展开图
看这个图我们会发现,这里存在两个第一张图和两个最后一张图,我们先看实现思路,至于为什么要有两个第一张图和两个最后一张图,后面讲解。
- 设置需要循环滑动的图片数组——dataArray
- 重新声明一个可变数组,增加两个元素,将dataArray的最后一个元素增加成为可变数组的第一个元素,将dataArray的第一个元素添加到可变数组的最后。然后将可变数组赋值给dataArray:
NSMutableArray * tempArray = [NSMutableArray arrayWithArray:self.dataArray];
[tempArray insertObject:[self.dataArray lastObject] atIndex:0];
[tempArray addObject:[self.dataArray firstObject]];
self.dataArray = [tempArray copy];
- 实现UIScrollView的代理:
-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
if (scrollView.contentOffset.x <= 0) {
[scrollView setContentOffset:CGPointMake(self.view.frame.size.width*(self.dataArray.count-2), 0) animated:NO];
}else if (scrollView.contentOffset.x >= self.view.frame.size.width*(self.dataArray.count - 1)){
[scrollView setContentOffset:CGPointMake(self.view.frame.size.width, 0) animated:NO];
}
}
- 当当前位置为dataArray的index==1,显示的是第一张图片时,用户操作了向右滑,这样的话就满足了scrollView.contentOffset.x <= 0,为什么满足?因为index==1时继续右滑,index将变为0,这时候scrollView.contentOffset.x就会等于0,然后就会执行改变UIScrollView偏移的代码。然后UIScrollView的位置就会从(0,0)变为(W*(count-2)),对照上图可以看出这样就实现了从第一张滑动到了最后一张了。
- 当当前位置为dataArray的index==count-2,显示的是最后一张图时,用户操作了向左滑,滑动结束之后,UIScrollView应该到index==count-1的位置,也就满足了scrollView.contentOffset.x >= self.view.frame.size.width*(self.dataArray.count - 1)的条件,然后我们改变UIScrollView的位置为(W,0)的位置,这样就又回到了第一张图的位置。
- 这样我们就可以看出这两张图的用处了,添加这两张图是为了过度,如果不要这两张,然后在代理里调整位置,会有问题。这两张图片为什么要这样放?因为UIScrollView在改变位移的时候,在移动的时候还是会短暂的出现中间被跳过的图片,而这样设置,第一张经过最后一张图片再到达真正的最后一张图片的位置,用户就看不出来那个过度。我们可以对比看一下效果。
- 正常按上图位置插入的图片效果:
- 随意在首尾各添加一张图的效果:
- 最后要注意的是,在设置偏移的时候一定要关闭动画,否则无法实现循环的视觉效果。
这个弄清楚之后图片循环就实现了,如果要实现轮播加个定时器就可以了。