iOS实现无限循环轮播图效果

本文实例为大家分享了iOS实现无限循环轮播图的具体代码,供大家参考,具体内容如下

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

预览

思路

(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)

相关推荐

  • iOS实现带有缩放效果的自动轮播图

    本文实例为大家分享了iOS带有缩放效果的自动轮播图,供大家参考,具体内容如下 可直接设置frame然后加载到视图上使用. 效果就是这样的,图片切换的过程中还是有卡顿,不够流畅,后续更新. 直接上代码. .h文件包含: #import <UIKit/UIKit.h> @interface CustomScrollView : UIView @property (strong,nonatomic) NSArray *imageArr; @end .m文件包含: #import "Cust

  • iOS使用UIScrollView实现无限循环轮播图效果

    本文实例为大家分享了iOS使用UIScrollView实现无限循环轮播图的具体代码,供大家参考,具体内容如下 代码: // // ViewController.m // 无限轮播 // // Created by limin on 17/8/23. // Copyright © 2017年 none. All rights reserved. // #import "ViewController.h" @interface ViewController ()<UIScrollVi

  • iOS实现轮播图banner示例

    楼主项目中需要有一个轮播图,因为比较简单,就自己写了个,因为是从网上弄得图片 所以用了SDWebImage 这个三方库 当然自己也可以去掉 类型后面有*号 如用使用 请自行加上..... 代码:.h 文件 @protocol TJXViewDelegate<NSObject> //判断点击的那个 -(void)sendImageName:(TJXView *)TJXView andName:(NSInteger)selectImage; @end @interface TJXView : UI

  • IOS 开发之网络图片轮播图的实现

    IOS 开发之网络图片轮播图的实现 截图 1.使用 LJPhotoGroupView *_ljPhotoGroupView = [[LJPhotoGroupView alloc]initWithItem:self.ljUrlArray]; _ljPhotoGroupView.backgroundColor = [UIColor blackColor]; _ljPhotoGroupView.frame = CGRectMake(0, 0, kDEVICEWIDTH, kDEVICEHEIGHT);

  • iOS实现无限循环轮播图效果

    本文实例为大家分享了iOS实现无限循环轮播图的具体代码,供大家参考,具体内容如下 轮播图基础控件,左滑右滑都能无限循环 预览 思路 (1)在第一张左边加一张最后一张的图片,往左滑到边缘结束后计算偏移量迅速定位成最后一张 #pragma mark - pagecontrol事件 // 这个是点击小圆点条进行切换,到边不能循环 - (void)pageControlTouched { // 点击的时候停止计时 [self.kvTimer setFireDate:[NSDate distantFutu

  • 原生js实现无限循环轮播图效果

    知识要点 1.实现无限循环的原理: 以偏移的距离来判断是否跳回第一张和最后一张 也可以利用循环判断图片的当前索引值 var newLeft=parseInt(list.style.left)+offset;//当前的偏移量+下一次的偏移量=新的偏移量 list.style.left=newLeft+"px";//当前的偏移值=新的偏移值 //以偏移的距离来判断是否跳回第一张和最后一张 if(newLeft>-600){ list.style.left=-3000+"px

  • 无限循环轮播图之运动框架(原生JS实现)

    封装运动框架 function getStyle(obj,name){ if(obj.currentStyle){ return obj.currentStyle[name]; }else{ return getComputedStyle(obj,false)[name]; } } function move(obj,json,options){ var options=options || {}; var duration=options.duration || 800; var easing

  • Android Viewpager实现无限循环轮播图

    在网上找了很多viewpager实现图片轮播的,但是大多数通过以下方式在PagerAdapter的getCount()返回一个无限大的数,来实现 伪无限 @Override public int getCount() { return Integer.MAX_VALUE;//返回一个无限大的值,可以 无限循环 } 虽然通过这种方式是能达到效果,但是从严格意义上来说并不是真正的无限. 假如有五张轮播图 item的编号为(0,1,2,3,4) 要想实现 无限循环  我们在这五张的头部和尾部各加一张即

  • iOS简单实现轮播图效果

    本文实例为大家分享了iOS简单实现轮播图效果的具体代码,供大家参考,具体内容如下 平常在开发过程中,首页的轮播图总是少不了,轮播图我们都知道肯定是要使用 UIScrollView ,难点就在最后一张图片被滑动时,如何回到第一张图片以及第一张滑动到最后一张.我们可以使用如下方式实现轮播图,在划到3后面的1后,设置 contentOffset 回到最先的1,并设置 pageControl ,即可达到效果 (从1划到3也同理) 看一下效果: 完成这种轮播图,我们的 View 需要如下的属性和方法 @i

  • Android ViewPager实现无限循环轮播广告位Banner效果

    现在一些app通常会在头部放一个广告位,底部放置一行小圆圈指示器,指示广告位当前的页码,轮播展示一些图片,这些图片来自于网络.这个广告位banner是典型的android ViewPager实现,但是如果自己实现这样的ViewPager,要解决一系列琐碎的问题,比如: (1)这个广告位ViewPager要支持无限循环轮播,例如,有3张图片,A,B,C,当用户滑到最后C时候再滑就要滑到A,反之亦然. (2)ViewPager要实现自动播放,比如每个若干秒如2秒,自动切换播放到下一张图片. (3)通

  • Android仿京东淘宝自动无限循环轮播控件思路详解

    在App的开发中,很多的时候都需要实现类似京东淘宝一样的自动无限轮播的广告栏,所以就自己写了一个,下面是我自定义控件的思路和过程. 一.自定义控件属性 新建自定义控件SliderLayout继承于RelativeLayout,首先要考虑的就是自定义的控件需要扩展那些属性,把这些属性列出来.在这里是要实现类似于京东淘宝的无限轮播广告栏,那么首先想到的就是轮播的时长.轮播指示器的样式等等.我在这里列举了一些并且结合到了代码中. 1.扩展属性 (1)是否开启自动轮播的功能. (2)指示器的图形样式,一

  • Android实现ViewPage轮播图效果

    在android移动端的开发中,首页轮播图是一个特别常见的功能,所以今天就来将最近写的一个小demo记录一下. 首先当然是新建一个项目代码如下: activity_main.xml文件: <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:to

  • 原生JS实现pc端轮播图效果

    本文实例为大家分享了JS实现pc端轮播图效果的具体代码,供大家参考,具体内容如下 案例:轮播图需求 布局:ul下有很多li标签:浮动在一行: 原理:切换图片的时候,把ul位置修改一下,给ul的父容器,设置一个 overflow:hidden: 功能需求: 序号轮播 左右按钮的轮播 自动轮播 鼠标在轮播图里面的时候,停止自动轮播,离开后继续自动轮播 实现效果: html部分 <div class="box" id="box"> <div class=

随机推荐