CollectionView 無限輪播設計思路

個人大體設計思路以下:git

  • 定時器。用於在固定的間隔滾動一頁
  • collectionView,自定義一個cell用於輪播展現
  • 對collectionView的數據源A進行處理。新建一個數組B,把A數組的最後一個添加到B數組的第一個,把A數組的第一個添加到B數組的最後一個。這樣B數組中就比源數組A多了兩個數據。在(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section 中返回的是數組B的長度
  • 在scrollview的相關代理方法中處理相應人爲拖動操做和滾動

下面結合代碼來講每步的具體實現:github

  1. 每隔固定的時間調用此方法實現滾動
-(void)startScrollAutomtically { // 每次加 self.bounds.size.width 寬度
    [self setContentOffset:CGPointMake(self.contentOffset.x + self.bounds.size.width, self.contentOffset.y) animated:YES];
}
或者使用

 [_mainView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:1 inSection:0] atScrollPosition:UICollectionViewScrollPositionNone animated:YES];

2.對數據源進行處理 若是原始數據源的長度大於一個則啓動定時器,反之不啓動定時器。若是原始數據源的長度大於一個則須要處理數據源,即上面3所說的。另外刷新完數據源則默認滾動到第一頁數組

- (void)configWithData:(NSArray<id<JWCBannerDataProtocol>> *)datas {
    if (_originalData.count > 1) {
        NSMutableArray *tempArr = [[NSMutableArray alloc] initWithArray:_originalData];
        [tempArr insertObject:[_originalData lastObject] atIndex:0];
        [tempArr addObject:[_originalData firstObject]];
        self.customData = tempArr.copy;
        dispatch_async(dispatch_get_main_queue(), ^{
            [self scrollToPage:1 animated:YES];
        });
        [self startTimer];
        self.isOnlyOne = NO;
    } else {
        self.customData = _originalData.copy;
        [self stopTimer];
        self.isOnlyOne = YES;
        self.currentIndex = 0;
    }
}

3 scrollView的幾個代理方法async

// 將要開始拖拽 中止定時器
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
    [self stopTimer];
}
// 將要中止拖拽 開始定時器
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset {
    if (_originalData.count > 1) { //若是數據源大於1 才啓動定時器
        [self startTimer];
    }
}
// 中止拖動
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    [self checkPageIndx];
}
// 動畫中止
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView {
    [self checkPageIndx];
}

// 此方法是人爲拖動完成須要作的處理動畫

- (void)checkPageIndx {
    //當滾動到最後一張圖片時,繼續滾向後動跳到page 1
    if (self.contentOffset.x >= (self.customData.count - 1) * self.bounds.size.width) {
        [self scrollToPage:1 animated:NO];
    }
    //當滾動到第一張圖片時,繼續向前滾動跳到倒數第二
    if (self.contentOffset.x < 0) {
        [self scrollToPage:self.customData.count - 2 animated:NO];
    }
}

// 中止滾動 計算當前的index 此方法是不管人爲仍是自動改變scrollview的 offset 都會調用此方法 因此在此方法中計算當前的index 這個index可用於顯示頁碼spa

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    CGFloat width = self.frame.size.width;
    NSInteger index = (scrollView.contentOffset.x + width * 0.5 ) / width;
    if (index == 0) {
        index = _originalData.count - 1;
    } else if (index >= _customData.count - 1) {
        index = 0;
    } else {
        index = index - 1;
    }
    self.currentIndex = index;
}

以上只是寫了大體的思路,具體的實現代碼在Git設計

相關文章
相關標籤/搜索