iOS开发:无限循环轮播图

来源:互联网 发布:非诚勿扰网络播出时间 编辑:程序博客网 时间:2024/04/27 00:42

轮播图基础控件,左滑右滑都能无限循环


预览



思路

(1)在第一张左边加一张最后一张的图片,往左滑到边缘结束后计算偏移量迅速定位成最后一张


#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];}

源代码下载

csdn:轮播图
github:轮播图


0 0
原创粉丝点击