轮播图基础控件,左滑右滑都能无限循环
#pragma mark - pagecontrol事件
// 这个是点击小圆点条进行切换,到边不能循环
- (void)pageControlTouched
{
// 点击的时候停止计时
[self.kvTimer setFireDate:[NSDate distantFuture]];
// 滑到指定页面
NSInteger curPageIdx = _pageControl.currentPage;
CGFloat offsetX = self.frame.size.width * (curPageIdx + 1);
[self.scrollView setContentOffset:CGPointMake(offsetX, 0) animated:YES];
// 重新开启定时器
[self.kvTimer setFireDate:[NSDate dateWithTimeInterval:kTimerInterval sinceDate:[NSDate date]]];
}
#pragma mark - 滚动事件
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
// printf("start drag\n");
// 记录偏移量
preOffsetX = scrollView.contentOffset.x;
// 开始手动滑动时暂停定时器
[self.kvTimer setFireDate:[NSDate distantFuture]];
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
// printf("end drag\n");
// 左右边界
CGFloat leftEdgeOffsetX = 0;
CGFloat rightEdgeOffsetX = self.frame.size.width * (_pageCount + 1);
if (scrollView.contentOffset.x < preOffsetX)
{
// 左滑
if (scrollView.contentOffset.x > leftEdgeOffsetX)
{
self.pageControl.currentPage = scrollView.contentOffset.x / self.frame.size.width - 1;
}
else if (scrollView.contentOffset.x == leftEdgeOffsetX)
{
self.pageControl.currentPage = _pageCount - 1;
}
if (scrollView.contentOffset.x == leftEdgeOffsetX)
{
self.scrollView.contentOffset = CGPointMake(self.frame.size.width * _pageCount, 0);
}
}
else
{
// 右滑
// 设置小点
if (scrollView.contentOffset.x < rightEdgeOffsetX)
{
self.pageControl.currentPage = scrollView.contentOffset.x / self.frame.size.width - 1;
}
else if (scrollView.contentOffset.x == rightEdgeOffsetX)
{
self.pageControl.currentPage = 0;
}
// 滑动完了之后从最后多余页赶紧切换到第一页
if (scrollView.contentOffset.x == rightEdgeOffsetX)
{
self.scrollView.contentOffset = CGPointMake(self.frame.size.width, 0);
}
}
// 结束后又开启定时器
[self.kvTimer setFireDate:[NSDate dateWithTimeInterval:kTimerInterval sinceDate:[NSDate date]]];
}
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView
{
// printf("end scroll\n");
}
#pragma mark - 定时器控制的滑动
// 往右边滑
- (void)changePageRight
{
// 设置当前需要偏移的量,每次递增一个page宽度
CGFloat offsetX = _scrollView.contentOffset.x + CGRectGetWidth(self.frame);
// 根据情况进行偏移
CGFloat edgeOffsetX = self.frame.size.width * (_pageCount + 1); // 最后一个多余页面右边缘偏移量
// 从多余页往右边滑,赶紧先设置为第一页的位置
if (offsetX > edgeOffsetX)
{
// 偏移量,不带动画,欺骗视觉
self.scrollView.contentOffset = CGPointMake(self.frame.size.width, 0);
// 这里提前改变下一个要滑动到的位置为第二页
offsetX = self.frame.size.width * 2;
}
// 带动画滑动到下一页面
[self.scrollView setContentOffset:CGPointMake(offsetX, 0) animated:YES];
if (offsetX < edgeOffsetX)
{
self.pageControl.currentPage = offsetX / self.frame.size.width - 1;
}
else if (offsetX == edgeOffsetX)
{
// 最后的多余那一页滑过去之后设置小点为第一个
self.pageControl.currentPage = 0;
}
}
// 往左边滑
- (void)changePageLeft
{
// 设置当前需要偏移的量,每次递减一个page宽度
CGFloat offsetX = _scrollView.contentOffset.x - CGRectGetWidth(self.frame);
// 根据情况进行偏移
CGFloat edgeOffsetX = 0; // 最后一个多余页面左边缘偏移量
// 从多余页往左边滑动,先设置为最后一页
if (offsetX < edgeOffsetX)
{
self.scrollView.contentOffset = CGPointMake(self.frame.size.width * _pageCount, 0);
offsetX = self.frame.size.width * (_pageCount - 1);
}
// 带动画滑动到前一页面
[self.scrollView setContentOffset:CGPointMake(offsetX, 0) animated:YES];
if (offsetX > edgeOffsetX)
{
self.pageControl.currentPage = offsetX / self.frame.size.width - 1;
}
else if (offsetX == edgeOffsetX)
{
// 最后的多余那一页滑过去之后设置小点为最后一个
self.pageControl.currentPage = _pageCount - 1;
}
}
(2)总共只有左、中、右三个页面,每次滑动后重新进行数据跟页面的关联
#pragma mark - 定时器回调
- (void)changePageRight
{
// 往右滑并且设置小圆点,永远都是滑到第三页
[_scrollView setContentOffset:CGPointMake(self.frame.size.width * 2, 0) animated:YES];
[self resetPageIndex:YES];
}
- (void)changePageLeft
{
// 往左滑,永远都是滑动到第一页
[_scrollView setContentOffset:CGPointMake(0, 0) animated:YES];
[self resetPageIndex:NO];
}
#pragma mark - 重新设置索引和页面图片
- (void)resetPageIndex:(BOOL)isRight
{
if (isRight)
{
// 根据之前的page下标来修改
if (_prePageIndex == _pageCount - 1)
{
// 到头了就回到第一个
_pageControl.currentPage = 0;
}
else
{
// 这里用_prePageIndex来算,否则点击小圆点条会重复计算了
_pageControl.currentPage = _prePageIndex + 1;
}
}
else
{
if (_prePageIndex == 0)
{
_pageControl.currentPage = _pageCount - 1;
}
else
{
_pageControl.currentPage = _prePageIndex - 1;
}
}
_prePageIndex = _pageControl.currentPage;
}
- (void)resetPageView
{
// 每次滑动完了之后又重新设置当前显示的page时中间的page
UIImageView *leftPage = [_scrollView viewWithTag:1000];
UIImageView *middlePage = [_scrollView viewWithTag:1001];
UIImageView *rightPage = [_scrollView viewWithTag:1002];
if (_pageControl.currentPage == _pageCount - 1)
{
// n- 1 -> n -> 0
leftPage.image = _kvImageArray[_pageControl.currentPage - 1];
middlePage.image = _kvImageArray[_pageControl.currentPage];
rightPage.image = _kvImageArray.firstObject;
}
else if (_pageControl.currentPage == 0)
{
// n -> 0 -> 1
// 到尾部了,改成从头开始
leftPage.image = _kvImageArray.lastObject;
middlePage.image = _kvImageArray.firstObject;
rightPage.image = _kvImageArray[1];
}
else
{
// x - 1 -> x -> x + 1
leftPage.image = _kvImageArray[_pageControl.currentPage - 1];
middlePage.image = _kvImageArray[_pageControl.currentPage];
rightPage.image = _kvImageArray[_pageControl.currentPage + 1];
}
// 重新设置偏移量
_scrollView.contentOffset = CGPointMake(self.frame.size.width, 0);
}
#pragma mark - pagecontrol事件
- (void)pageControlTouched
{
[self stopTimer];
NSInteger curPageIndex = _pageControl.currentPage;
if (curPageIndex > _prePageIndex)
{
// 右滑
[self changePageRight];
}
else
{
// 左滑
[self changePageLeft];
}
[self startTimer];
}
#pragma mark - scrollview滑动代理
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
// 先停掉定时器
[self stopTimer];
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
// 手动拖拽滑动结束后
if (scrollView.contentOffset.x > self.frame.size.width)
{
// 右滑
[self resetPageIndex:YES];
}
else
{
// 左滑
[self resetPageIndex:NO];
}
[self resetPageView];
// 开启定时器
[self startTimer];
}
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView
{
// 自动滑动结束后重新设置图片
[self resetPageView];
}