个人大体设计思路以下:git
- 定时器。用于在固定的间隔滚动一页
- collectionView,自定义一个cell用于轮播展现
- 对collectionView的数据源A进行处理。新建一个数组B,把A数组的最后一个添加到B数组的第一个,把A数组的第一个添加到B数组的最后一个。这样B数组中就比源数组A多了两个数据。在(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section 中返回的是数组B的长度
- 在scrollview的相关代理方法中处理相应人为拖动操做和滚动
下面结合代码来讲每步的具体实现:github
-(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设计