1.數(shù)據(jù)容器 (輪播器的圖片容器)
@property (strong,nonatomic) NSArray *imgDataArr;
2.實(shí)現(xiàn)CollectionView的UICollectionViewDataSource數(shù)據(jù)源方法
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
//將容器數(shù)組長(zhǎng)度*2 (多出一組Item)
return self. imgDataArr.count * 2;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
static NSString * const reuseIdentifier = @"Cell";
JSCycleCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath];
//這里設(shè)置背景色是因?yàn)镮mageView的Size小于itemSize,留個(gè)邊框的效果
cell.backgroundColor = [UIColor whiteColor];
/*
因?yàn)閕tem個(gè)數(shù)*2, 但容器的真實(shí)長(zhǎng)度并未改變,所以取數(shù)據(jù)源的時(shí)候?qū)θ萜鏖L(zhǎng)度取模,就可以取到對(duì)應(yīng)索引的圖片
拿總長(zhǎng)度為4 舉例
(原始的數(shù)據(jù)源cycleList的長(zhǎng)度是4, 但是我們現(xiàn)在item有8個(gè), 我們不能直接根據(jù) indexpath.item 去取數(shù)據(jù))
0%4 = 0 , 1%4=1, 2%4=2, 3%4=3;
4%4 = 0 , 5%4=1, 6%4=2, 7%4=3
*/
//這里我自定義了一個(gè)Cell,傳遞屬性并賦值與這里直接設(shè)置Item里的ImageView原理一樣
cell.imgModel = self. imgDataArr[indexPath.item % self. imgDataArr.count];
return cell;
}
3.實(shí)現(xiàn)CollectionView的UICollectionViewDelegate代理方法(UICollectionView繼承自UIScrollView)計(jì)算滑動(dòng)停止時(shí),當(dāng)前顯示哪一個(gè)Item
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
//獲取當(dāng)前CollectionView的偏移量
CGFloat offSetX = scrollView.contentOffset.x;
/*
拿總長(zhǎng)度為4 舉例:
初始時(shí),讓索引為4的Item為默認(rèn)顯示的Item(第2組第1張)
當(dāng)偏移量等于0時(shí)(第1組第1張,也就是第一張圖片),以無(wú)動(dòng)畫(huà)的方式悄悄的跳轉(zhuǎn)回索引為4的Item(第2組第1張)
當(dāng)偏移量等于7倍CollectionView的寬度時(shí)(第2組第4張,也就是最后一張圖片),同樣以無(wú)動(dòng)畫(huà)的方式跳轉(zhuǎn)回索引為3的Item(第1組第4張)
因?yàn)閮山M圖片是一致的,又是以無(wú)動(dòng)畫(huà)無(wú)察覺(jué)的方式跳轉(zhuǎn)的,所以就可以實(shí)現(xiàn)無(wú)限輪播的效果了
*/
if (offSetX == 0) {
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:self.cycleModelArr.count inSection:0];
[self.collectionView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionNone animated:NO];
}else if (offSetX == scrollView.bounds.size.width * ( self.cycleModelArr.count * 2 - 1 )){
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:self.cycleModelArr.count - 1 inSection:0];
[self.collectionView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionNone animated:NO];
}
}
細(xì)節(jié):
1.FlowLayout:讓collectionView的item 自動(dòng)適配
因?yàn)樵赩IewDidLoad中并不能獲取到真實(shí)有效的Frame,所以在設(shè)置FlowLayout時(shí),要寫(xiě)在viewDidLayoutSubviews或者是viewDidAppear中
- (void)viewDidLayoutSubviews{
self.flowLayout.itemSize = self.collectionView.bounds.size;
}
2.防止?jié)L動(dòng)條出賣(mài)自己,需要將滾動(dòng)條指示關(guān)掉(根據(jù)情況選擇禁用垂直\水平方向),并設(shè)置分頁(yè)效果
self.collectionView.showsVerticalScrollIndicator = NO;
self.collectionView.showsHorizontalScrollIndicator = NO;
self.collectionView.pagingEnabled = YES;
3.初始的時(shí)候,讓CollectionView默認(rèn)顯示索引為4的那個(gè)Item(第2組第1張圖片)
輪播-初始.png
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:self.imgDataArr.count inSection:0];
[self.collectionView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionNone animated:NO];
這樣就能簡(jiǎn)單的實(shí)現(xiàn)一個(gè)無(wú)限輪播器效果了.