在iOS開發(fā)中其實(shí)無(wú)限輪播是一個(gè)很常見的UI組件,在沒有UICollectionView之前一般都是用UIScrollView去實(shí)現(xiàn)的,在本文中主要是記錄下無(wú)限輪播用的實(shí)現(xiàn)思路.
這個(gè)系列一共介紹兩種思路,本文先來介紹第一種思路:
思路一
大致的思路是這樣的:在ScrollView上一共放n+2個(gè)內(nèi)容(n代表要展示的圖片數(shù)),例如我現(xiàn)在要展示5張圖片,那么n+2的話就需要7張圖片,那么圖片的順序依次是:圖片5,圖片1,圖片2,圖片3,圖片4,圖片5,圖片1,當(dāng)我滾動(dòng)到第七張的時(shí)候,我們展示的是圖片1,這時(shí)候我們要將設(shè)置ContentOffset來將ScrollView滾動(dòng)到第二張的位置(也是圖片1),這個(gè)時(shí)候用戶繼續(xù)劃動(dòng)的話,下一張圖片就是圖片2了,這樣可以給用戶制造出一種無(wú)限滑動(dòng)的假象,那么用戶往回劃的時(shí)候劃到第一張(圖片5)的時(shí)候,將ScrollView滾動(dòng)到第六張圖片的位置(也是圖片5),這樣在繼續(xù)往回劃動(dòng)的話就滾動(dòng)到了圖片4的位置.
我們來看下代碼:
- 設(shè)置展示的圖片數(shù)據(jù)源
- (void)setimagesArray:(NSArray<NSString *> *)imageNamesArray
{
NSInteger arrayCount = imageNamesArray.count + 2;
// 拼接數(shù)據(jù)源數(shù)組
NSMutableArray *tempImageNamesArray = [NSMutableArray arrayWithCapacity:arrayCount];
[tempImageNamesArray addObject:[imageNamesArray lastObject]];
[tempImageNamesArray addObjectsFromArray:imageNamesArray];
[tempImageNamesArray addObject:[imageNamesArray firstObject]];
// 創(chuàng)建圖片數(shù)組
NSMutableArray *tempImagesArray = [NSMutableArray arrayWithCapacity:arrayCount];
[tempImageNamesArray enumerateObjectsUsingBlock:^(NSString * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
CGRect imageViewFrame = CGRectMake(idx * self.frame.size.width, 0, self.frame.size.width, self.frame.size.height);
UIImage *image = [UIImage imageNamed:obj];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
imageView.frame = imageViewFrame;
[tempImagesArray addObject:imageView];
}];
_imagesArray = tempImagesArray.copy;
}
- 我們需要將
ScrollView滾動(dòng)到第二張的位置(圖片1).
// (0, 0)為起始位置,要展示第二張圖片要設(shè)置ScrollView的位置
[self.scrollView setContentOffset:CGPointMake(self.frame.size.width, 0) animated:NO];
在滾動(dòng)過程我們需要用到UIScrollViewDelegate中的scrollViewDidEndDecelerating:方法來判定是否需要回滾到我們指定的位置,這個(gè)方法是整個(gè)思路的核心,代碼如下:
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
// 根據(jù)偏移量獲取到當(dāng)前展示的是圖片幾
NSInteger pageNum = scrollView.contentOffset.x / self.frame.size.width;
/*
判斷如果當(dāng)前展示的是否是最后一張圖片(圖片1),
如果是的話就滾動(dòng)到第二張圖片(圖片1)的位置
如果當(dāng)前展示的是第一張圖片(圖片5)的話就滾動(dòng)到第六張(圖片5)的位置
*/
if (pageNum == _imagesArray.count - 1)
{
[scrollView setContentOffset:CGPointMake(self.frame.size.width, 0) animated:NO];
self.pageControl.currentPage = 0;
return;
}
else if (pageNum == 0)
{
[scrollView setContentOffset:CGPointMake(self.frame.size.width * (_imagesArray.count - 2), 0) animated:NO];
self.pageControl.currentPage = _imagesArray.count - 2;
return;
}
// 設(shè)置pageControl的currentPage數(shù)
self.pageControl.currentPage = pageNum - 1;
}
這里還要說明下,最終用戶看到的其實(shí)就是我們需要展示的5張圖片,那么PageControl的numberOfPages就是5.
以上就是整個(gè)思路的大概流程.
再補(bǔ)充下上面說到的是手動(dòng)拖動(dòng)的流程,那么我們?nèi)粘5目匆姷臒o(wú)線輪播都是自動(dòng)播放的,那么這里就需要增加一個(gè)定時(shí)器來定時(shí)執(zhí)行滑動(dòng)方法
- (void)scrollAnimation
{
// 獲取當(dāng)前正在第幾頁(yè)
NSInteger pageNum = self.scrollView.contentOffset.x / self.frame.size.width;
// 滾動(dòng)到下一頁(yè)
[self.scrollView setContentOffset:CGPointMake(self.frame.size.width * (pageNum + 1), 0) animated:YES];
self.pageControl.currentPage = pageNum;
}
其中setContentOffset:(CGPoint)contentOffset animated:(BOOL)animated;這個(gè)方法中如果后面那個(gè)參數(shù)填寫的YES的話就會(huì)調(diào)用UIScrollViewDelegate中的scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView這個(gè)方法,由于是往一個(gè)方向移動(dòng)所以不用關(guān)注反向操作
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView
{
// 如果當(dāng)前展示的是最后一張圖片(圖片1), 就滾動(dòng)到第二張圖片(圖片1)的位置
NSInteger pageNum = self.scrollView.contentOffset.x / self.frame.size.width;
if (pageNum == _imagesArray.count - 1)
{
self.pageControl.currentPage = 0;
[self.scrollView setContentOffset:CGPointMake(self.frame.size.width, 0) animated:NO];
}
}
以上就是思路一中所有的大致流程.接下來的一篇文章中會(huì)說一下另外一種方式,而另一種方式是這個(gè)思路一的升級(jí)版.