UICollectionView的无限轮播

本是想研究下UICollectionView的横向滑动,然而仔细想想要不就索性做一个轮播器吧。

首先看看成果:

demo

丑是丑了点但接触到的知识点还是不少的.接下来讲解下主要思路和关键代码。

1.首先必然是要写出UICollectionView横向滑动的效果。因为是横向滑动所以UICollectionViewFlowLayout的scrollDirection自能设置为UICollectionViewScrollDirectionHorizontal。

1
layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;

2.就是设置Layout的minimumLineSpacing属性。如果设置的minimumLineSpacing的值大于0时,在之后设置循环显示时一定要把该值考虑进去,不然是很容易出现循环显示错误。

3.UICollectionView横向滑动设置好后可以通过NSTimer来实现自动轮播。

  • 设置定时器
1
2
3
NSTimer *timer = [NSTimer timerWithTimeInterval:self.automaticallyScrollDuration target:self selector:@selector(showNext) userInfo:nil repeats:true];

[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];

self.automaticallyScrollDuration 为循环时间

  • 实现轮播代码
1
2
3
4
5
6
7
//自动显示下一个
- (void)showNext {
//手指拖拽是禁止自动轮播
if (_collectionView.isDragging) {return;}
CGFloat targetX = _collectionView.contentOffset.x + _collectionView.bounds.size.width;
[_collectionView setContentOffset:CGPointMake(targetX, 0) animated:true];
}
  • 实现UIScrollViewDelegate代理方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//手动拖拽结束
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
[self cycleScroll];
//拖拽动作后间隔3s继续轮播
[_timer setFireDate:[NSDate dateWithTimeIntervalSinceNow:self.automaticallyScrollDuration]];
}

//自动轮播结束
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView {
[self cycleScroll];
}

//循环显示
- (void)cycleScroll {
NSInteger page = _collectionView.contentOffset.x/_collectionView.bounds.size.width;
if (page == 0) {//滚动到左边
_collectionView.contentOffset = CGPointMake(_collectionView.bounds.size.width * (_mutableImageArray.count - 2), 0);
_pageControl.currentPage = _mutableImageArray.count - 2;
}else if (page == _mutableImageArray.count - 1){//滚动到右边
_collectionView.contentOffset = CGPointMake(_collectionView.bounds.size.width, 0);
_pageControl.currentPage = 0;
}else{
_pageControl.currentPage = page - 1;
}
}

4.实现循环轮播需要改变数据源来实现。

  • 分别设置两个属性
1
2
@property (nonatomic, copy) NSArray *dataArray; // 图片数据
@property (nonatomic, strong) NSMutableArray *mutableImageArray; // 循环图片数组

dataArray存储要显示的图片数组 mutableImageArray是用来实现循环轮播的图片数组

1
2
3
4
5
6
7
8
9
10

- (NSMutableArray *)mutableImageArray {
if (self.dataArray.count > 0) {
_mutableImageArray = [NSMutableArray arrayWithArray:self.dataArray];
[_mutableImageArray addObject:self.dataArray.firstObject];// 把原数组的第一个数据插入到最后面生成一个新的数组
[_mutableImageArray insertObject:[self.dataArray lastObject] atIndex:0];// 把原数组的最后一个数据插入到最前面生成一个新的数组
_pageControl.numberOfPages = self.dataArray.count;
}
return _mutableImageArray;
}

🌰 dataArray = 12345 那么mutableImageArray = 5123451 为什么要获取这样的数组呢?我的理解是当轮播到最后一张图片(mutableImageArray最后一位的1)时,直接显示mutableImageArray的第二位的1.(即通过设置ScrollView的ContentOffset来显示)

5.在4中还要个问题就是默认值

1
[_collectionView setContentOffset:CGPointMake(_collectionView.bounds.size.width, 0)];

6.UIPageControl的设置在实现循环轮播中就应该考虑进去

  • 详细代码见DEMO

  • 有错误和不足不吝赐教!!!!!!