UICollectionView實現無限輪播

#import "KGNewsController.h"
#import "KGNewsCell.h"
#import "KGNews.h"
#import "MJExtension.h"

// 生成一個字符串
#define NSString(...) [NSString stringWithFormat:__VA_ARGS__]

#define KGCount 100

@interface KGNewsController ()<UICollectionViewDataSource, UICollectionViewDelegate>
@property (strong, nonatomic) IBOutlet UICollectionView *collectionView;
/** 模型數組 */
@property (strong, nonatomic) NSArray *dataSourceArr;
@property (strong, nonatomic) UIPageControl *pageControl;
@property (strong, nonatomic) NSTimer *timer;
@end

@implementation KGNewsController
- (NSArray *)dataSourceArr {
    if (!_dataSourceArr) {
        // 模型數組
        _dataSourceArr = [KGNews objectArrayWithFilename:@"newses.plist"];
    }
    return _dataSourceArr;
}

static NSString *cell_id = @"KGNewsCell";

- (void)viewDidLoad {
    [super viewDidLoad];
   
    // 註冊nib裏面的cell
    [self.collectionView registerNib:[UINib nibWithNibName:@"KGNewsCell" bundle:[NSBundle mainBundle]] forCellWithReuseIdentifier:cell_id];
   
    // 100組中間開始展現圖片
    [self.collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:KGCount / 2] atScrollPosition:UICollectionViewScrollPositionLeft animated:YES];
   
    // 添加定時器
    [self addTimer];
   
    // 添加pageControll
    UIPageControl *pageControl = [[UIPageControl alloc] init];
    pageControl.center = CGPointMake(self.view.bounds.size.width / 2, 200);
    pageControl.pageIndicatorTintColor = [UIColor redColor];
    pageControl.currentPageIndicatorTintColor = [UIColor blackColor];
    [self.view addSubview:pageControl];
    pageControl.numberOfPages = 5;
    self.pageControl = pageControl;
}

/**
 *  添加定時器
 */
- (void)addTimer {
    // 1.建立定時器
    NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.5 target:self selector:@selector(nextPage) userInfo:nil repeats:YES];
   
    // 2.把定時器添加到mainRunLoop(主線程也會抽空處理NSTimer的事件)(若是不添加到mainRunLoop,用戶作其餘操做的時候,定時器就會中止工做)
    [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
    self.timer = timer;
}

/**
 *  移除定時器
 */
- (void)removeTimer {
    // 中止定時器
    [self.timer invalidate];
    // 清空定時器
    self.timer = nil;
}

/**
 *  顯示下一頁(保證使用定時器不會把100組都輪播完)
 */
- (void)nextPage {
    // 1.立刻顯示回最中間那組的數據
    NSIndexPath *currentIndexPath = [
    self resetIndexPath];
   
    // 2.計算下一個須要展現的位置(每次都在100組中間組開始)
    NSInteger nextItem = currentIndexPath.item + 1;
    NSInteger nextSection = currentIndexPath.section;
    if (nextItem == self.dataSourceArr.count) {
        nextItem = 0;
        nextSection ++;
    }
   
    NSIndexPath *nextIndexPath = [NSIndexPath indexPathForItem:nextItem inSection:nextSection];
   
    // 3.經過動畫滾動到下一個位置
    [self.collectionView scrollToItemAtIndexPath:nextIndexPath atScrollPosition:UICollectionViewScrollPositionLeft animated:YES];
   
    // 4.顯示頁碼
    self.pageControl.currentPage = nextItem;
}

/**
 *  重置indexPath
 */
- (NSIndexPath *)resetIndexPath {
    // 1.當前正在展現的位置
    NSIndexPath *currentIndexPath = [[self.collectionView indexPathsForVisibleItems] lastObject];
   
    // 立刻顯示回最中間那組的數據
    NSIndexPath *currentIndexPathReset = [NSIndexPath indexPathForItem:currentIndexPath.item inSection:KGCount / 2];
    [self.collectionView scrollToItemAtIndexPath:currentIndexPathReset atScrollPosition:UICollectionViewScrollPositionLeft animated:NO];
    return currentIndexPathReset;
}

#pragma mark - UICollectionViewDataSource
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
    return KGCount;
}

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    return self.dataSourceArr.count;
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    KGNewsCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cell_id forIndexPath:indexPath];
   
    // 傳給cell模型
    cell.news = self.dataSourceArr[indexPath.item];
   
    return cell;
}

#pragma mark - 監聽collectionView滾動
/**
 *  用戶開始拖拽collectionView
 */
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
    [self removeTimer];
}

/**
 *  當用戶中止拖拽(手指離開)
 */
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    [self addTimer];
}

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    int page = (int)(scrollView.contentOffset.x / scrollView.bounds.size.width + 0.5) % self.dataSourceArr.count;       self.pageControl.currentPage = page;}- (IBAction)testNSTimer:(UIButton *)sender {    for (int i = 0; i < 10; i ++) {        NSLog(@"測試:若是NSTimer不加入mainRunLoop的狀況下,點擊button,計時器是否還會工做--%d", i);    }}
@end
相關文章
相關標籤/搜索