UIScrollView + 多张 ImageView 实现轮播

实现原理:

将所有图片的名字储存在数组 imageAry 中,imageAry 的元素个数为 num,在 scrollView 上添加 num + 1 个 UIImageView,第一个 imageView 上放最后一张图片,第二个 imageView 上放第一张图片,依次类推,最后一个 imageView 上的图片和第一个 imageView 的图片相同,用来过渡。在初始状态将 scrollView 的 contentOffset 的 x 值设为一个屏幕的宽度。

代码如下:

for (NSInteger i = 0; i < count + 1; i++) {
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(i * DEVICE_WIDTH, 0, DEVICE_WIDTH, 500)];
NSString *imageName = self.imageAry[count-1];
if (i != 0) {
imageName = self.imageAry[i-1];
}
imageView.image = [UIImage imageNamed:imageName];
[self.scrollView addSubview:imageView];
}
  1. 手动轮播

    当手动滚动到倒数第二张图片,继续向右滚动时,设置 scrollView 的 contentOffset 的 x 值为 0,并不做动画,实现自然过渡到第一个 imageView,显示最后一张图片。

    当手动滚动到第一个 imageView,继续向左滚动时,设置 scrollView 的 contentOffset 的 x 值为图片的总个数乘以屏幕的宽度,并不做动画,实现自然过渡到最后一个 imageView,显示的也是最后一张图片。

    代码如下:

    - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    CGFloat offsetX = scrollView.contentOffset.x;
    NSInteger count = self.imageAry.count;
    if (offsetX < 0) {
    [scrollView setContentOffset:CGPointMake(count * DEVICE_WIDTH, 0) animated:NO];
    } else if (offsetX > count * DEVICE_WIDTH) {
    [scrollView setContentOffset:CGPointMake(0, 0) animated:NO];
    }
    }
  2. 自动轮播

    当自动滚动到倒数第二张图片,继续向右滚动时,设置 scrollView 的 contentOffset 的 x 值为 0,并不做动画,紧接着设置 scrollView 的 contentOffset 的 x 值为屏幕的宽度,并做动画,实现从最后一个 imageView 到第一个 imageView 的自然过渡。

    代码如下:

    - (void)autoPlay {
    [super autoPlay];
    CGFloat offsetX = self.scrollView.contentOffset.x;
    NSInteger count = self.imageAry.count;
    CGFloat imageViewX = DEVICE_WIDTH;
    if (offsetX > (count - 1) * DEVICE_WIDTH) {
    [self.scrollView setContentOffset:CGPointMake(0, 0) animated:NO];
    } else {
    imageViewX += offsetX;
    }
    [self.scrollView setContentOffset:CGPointMake(imageViewX, 0) animated:YES];
    }

UIScrollView + 3 张 ImageView 实现轮播

实现原理:

将所有图片的名字储存在数组 imageAry 中,imageAry 的元素个数为 num,在 scrollView 上添加 3 个 UIImageView,第一个 imageView 上放最后一张图片,第二个 imageView 上放第一张图片,第三个 imageView 上放第二张图片。在初始状态将 scrollView 的 contentOffset 的 x 值设为一个屏幕的宽度,即显示的是中间的 imageView。

代码如下:

for (NSInteger i = 0; i < 3; i++) {
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(i * DEVICE_WIDTH, 0, DEVICE_WIDTH, 500)];
NSString *imageName = self.imageAry[count-1];
if (i != 0) {
imageName = self.imageAry[i-1];
}
imageView.image = [UIImage imageNamed:imageName];
[self.scrollView addSubview:imageView];
}
  1. 手动轮播

    当 scrollView 的 contentOffset 的 x 值为 0 时,减小 pageControl 的 currentPage(如果 currentPage 为 0,则设置 currentPage 为最大)。

    当 scrollView 的 contentOffset 的 x 值为 2 倍的屏幕宽度时,变大 pageControl 的 currentPage(如果 currentPage 为最大,则设置 currentPage 为 0)。

    然后根据 currentPage 从数组中取出图片给 imageView 赋值。

    最后将 scrollView 的 contentOffset 的 x 值恢复到一个屏幕的宽度,且不做动画,即始终显示中间的 imageView。

    代码如下:

    - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    CGFloat offsetX = scrollView.contentOffset.x;
    if (offsetX == 0) {
    [self currentPageDown];
    [self resetImagesAndContentOffset];
    } else if (offsetX == 2 * DEVICE_WIDTH) {
    [self currentPageUp];
    [self resetImagesAndContentOffset];
    }
    } - (void)currentPageDown {
    NSInteger count = self.imageAry.count;
    NSInteger currentIndex = (self.pageControl.currentPage - 1 + count) % count;
    self.pageControl.currentPage = currentIndex;
    } - (void)currentPageUp {
    NSInteger currentIndex = (self.pageControl.currentPage + 1) % self.imageAry.count;
    self.pageControl.currentPage = currentIndex;
    } - (void)resetImagesAndContentOffset {
    NSInteger currentPage = self.pageControl.currentPage;
    NSInteger count = self.imageAry.count;
    for (NSInteger i = 0; i < 3; i++) {
    UIImageView *imageView = self.scrollView.subviews[i];
    NSInteger imageIndex = 0;
    switch (i) {
    case 0:
    imageIndex = currentPage - 1;
    if (imageIndex < 0) {
    imageIndex = count - 1;
    }
    break;
    case 1:
    imageIndex = currentPage;
    break;
    case 2:
    imageIndex = currentPage + 1;
    if (imageIndex > count - 1) {
    imageIndex = 0;
    }
    break;
    }
    imageView.image = [UIImage imageNamed:self.imageAry[imageIndex]];
    }
    [self.scrollView setContentOffset:CGPointMake(DEVICE_WIDTH, 0) animated:NO];
    }
  2. 自动轮播

    设置 scrollView 的 contentOffset 的 x 值为 2 倍的屏幕宽即可。

    代码如下:

    - (void)autoPlay {
    [super autoPlay];
    [self.scrollView setContentOffset:CGPointMake(2 * DEVICE_WIDTH, 0) animated:YES];
    }

Demo 下载

iOS -- 轮播图的更多相关文章

  1. 一步一步拆解一个简单的iOS轮播图(三图)

    导言(可以不看): 不吹不黑,也许是东半球最简单的iOS轮播图拆分注释(讲解不敢当)了(tree new bee).(一句话包含两个人,你能猜到有谁吗?提示:一个在卖手机,一个最近在卖书)哈哈... ...

  2. IOS轮播图

    轮播图播放的主要技术在于: cell的封装.这里采用UICollectionViewCell实现. #import <UIKit/UIKit.h> @interface CircleVie ...

  3. ReactNative新手学习之路04 组件化开发轮播图swiper支持安卓和IOS

    react native 新手之路04 组件化开发轮播图swiper支持安卓和IOS npm install react-native-carousel --save git 地址Properties ...

  4. iOS 图片轮播图(自动滚动)

    iOS 图片轮播图(自动滚动) #import "DDViewController.h" #define DDImageCount 5 @interface DDViewContr ...

  5. iOS回顾笔记(05) -- 手把手教你封装一个广告轮播图框架

    html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,bi ...

  6. iOS最笨的办法实现无限轮播图(网络加载)

    iOS最笨的办法实现无限轮播图(网络加载) 简单的做了一下: 使用方法: 把 请求返回的 图片地址(字符串类型)放进数组中就行 可以使用SDWebImage(我就是用的这个)等..需要自己导入并引用, ...

  7. iOS开发之 用第三方类库实现轮播图

    在github上面有很多的第三方类库,大大节约了大家的开发时间 下载地址:https://github.com/gsdios/SDCycleScrollView 现已支持cocoapods导入:pod ...

  8. iOS中 轮播图放哪最合适? 技术分享

    我们知道,轮播图放在cell或collectionViewCell上会影响用户层级交互事件,并且实现起来比较麻烦,现在推出一个技术点:答题思路是:将UIScrollView放在UIView或UICol ...

  9. iOS swift版本无限滚动轮播图

    之前写过oc版本的无限滚动轮播图,现在来一个swift版本全部使用snapKit布局,数字还是pageConrrol样式可选 enum typeStyle: Int { case pageContro ...

随机推荐

  1. BZOJ 3110: [Zjoi2013]K大数查询 [树套树]

    3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 6050  Solved: 2007[Submit][Sta ...

  2. 分布式服务注册和发现consul 简要介绍

    Consul是HashiCorp公司推出的开源工具,用于实现分布式系统的服务发现与配置.与其他分布式服务注册与发现的方案,Consul的方案更"一站式",内置了服务注册与发现框 架 ...

  3. Spring5:@Autowired注解、@Resource注解和@Service注解

    什么是注解 传统的Spring做法是使用.xml文件来对bean进行注入或者是配置aop.事物,这么做有两个缺点: 1.如果所有的内容都配置在.xml文件中,那么.xml文件将会十分庞大:如果按需求分 ...

  4. Angular2学习笔记——Observable

    Reactive Extensions for Javascript 诞生于几年前,随着angular2正式版的发布,它将会被更多开发者所认知.RxJs提供的核心是Observable对象,它是一个使 ...

  5. JavaScript的妙与乐(一)之 函数优化

    JavaScript的妙与乐系列文章主要是展示一些JavaScript上面比较好玩一点的特性和一些有用的技巧,里面很多内容都是我曾经在项目中使用过的一些内容(当然,未必所有技巧的使用频率都很高^_^) ...

  6. hibernate一对一外键双向关联

    关联是类(类的实例)之间的关系,表示有意义和值得关注的连接. 本系列将介绍Hibernate中主要的几种关联映射 Hibernate一对一主键单向关联Hibernate一对一主键双向关联Hiberna ...

  7. 深入MySQL索引

    MySQL索引作为数据库优化的常用手段之一在项目优化中经常会被用到, 但是如何建立高效索引,有效的使用索引以及索引优化的背后到底是什么原理?这次我们深入数据库索引,从索引的数据结构开始说起. 索引原理 ...

  8. 如何下载Github单个文件(Windows平台)

    如何下载Github单个文件(Windows平台) 前提 安装Chrome 浏览器 Chrome浏览器 安装迅雷软件 安装Chrome 迅雷插件 可能商店里迅雷插件有好几种,这里使用这一种 一般使用者 ...

  9. Android开发学习之路-使用annotationProcessor配置Butterknife

    Apt工具的作者宣布了不再维护该工具了,而且Android Studio也有了自己的插件,并且可以通过gradle来简单的配置. 其实用Butterknife的都知道,没有apt,onClick绑定不 ...

  10. php 查询

    <h1>租房信息</h1> <?php $db = ","asdadads"); $tj = "1=1"; $tj1 = ...