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. PADS Layout 颜色设置

    一.板框.装配线.标注线配置: 二.个人爱好,我一般把Top pads设置成为浅绿色,Top Trace/vias/2D Line/Text/Cooper设置成为深绿色,Error设置成为黄色,而Bo ...

  2. .NET基础拾遗(2)面向对象的实现和异常的处理基础

    Index : (1)类型语法.内存管理和垃圾回收基础 (2)面向对象的实现和异常的处理基础 (3)字符串.集合与流 (4)委托.事件.反射与特性 (5)多线程开发基础 (6)ADO.NET与数据库开 ...

  3. Windows Server 2012 磁盘管理之 简单卷、跨区卷、带区卷、镜像卷和RAID-5卷

    今天给客户配置故障转移群集,在Windows Server 2012 R2的系统上,通过iSCSI连接上DELL的SAN存储后,在磁盘管理里面发现可以新建 简单卷.跨区卷.带区卷.镜像卷.RAID-5 ...

  4. GIT服务器的四种协议

    本地协议 最基本的就是_本地协议(Local protocol)_,所谓的远程仓库在该协议中的表示,就是硬盘上的另一个目录.这常见于团队每一个成员都对一个共享的文件系统(例如 NFS)拥有访问权,或者 ...

  5. Html5 Json应用

    本文主要说明Json的基本概念,和一个在Html中使用Json给元素赋值的小例子,属于基础性信息 什么是 JSON ? JSON 指的是 JavaScript 对象表示法(JavaScript Obj ...

  6. jQuery? 回归JavaScript原生API

    如今技术日新月异,各类框架库也是层次不穷.即便当年漫山红遍的JQuery(让开发者write less, do more,So Perfect!!)如今也有被替代的大势.但JS原生API写法依旧:并且 ...

  7. 【.net 深呼吸】将目录树转化为文本

    大伙都知道,文件系统是树形结构的,有时候我们会想到把目录的层次结构变为纯文本形式,就像这样: ├─Windows-universal-samples-master │ ├─Samples │ │ ├─ ...

  8. Android ButterKnife配置使用

    ButterKnife在GitHub的地址:https://github.com/JakeWharton/butterknife 最新的版本是:8.4.0 app 模块的build.gradle: a ...

  9. ASP.NET MVC5+EF6+EasyUI 后台管理系统(29)-T4模版

    系列目录 本节不再适合本系统,在58,59节已经重构.请超过本节 这讲适合所有的MVC程序 很荣幸,我们的系统有了体验的地址了.演示地址 之前我们发布了一个简单的代码生成器,其原理就是读取数据库的表结 ...

  10. ASP.NET MVC5+EF6+EasyUI 后台管理系统(33)-MVC 表单验证

    系列目录 注:本节阅读需要有MVC 自定义验证的基础,否则比较吃力 一直以来表单的验证都是不可或缺的,微软的东西还是做得比较人性化的,从webform到MVC,都做到了双向验证 单单的用js实现的前端 ...