iOS 自定义图片无限轮播控件

这里写图片描述

一:简介

图片轮播功能在App中是一个非常常见的功能,即允许定时滚动,也允许拖拽滚动,也可以点击每张图片触发事件。


二:实现方式

图片轮播功能的实现方式有很多中,

  • UIScrollView + N个UIImageView
  • UIScrollView + 3个UIImageView
  • UICollectionView
  • 其它方式

1. UIScrollView + N个UIImageView

一般初学者都会采用这种方式:UIView作为父视图,将UIScrollView和UIPageControl添加到父视图UIView上,然后再将所有UIImageView从头到尾依次添加到UIScrollView上,滚动视图的偏移量 offset.x 默认为0。

这种方式最简单易懂,一般图片轮播功能的图片张数在10张以内,因为UIScrollView没有循环利用的功能,假如图片超过10张有很多张(比如100个)那么就要创建100个UIImageView,这是比较浪费内存的,显然这种方式只能玩玩不能用于实际开发当中。

这里写图片描述


2. UIScrollView + 3个UIImageView

方式一当图片个数过多的情况下会创建很多个UIImageView,为了解决这个问题,方式二将采用始终创建3个UIImageView的方式来处理。

该方式采用以UIView作为父视图,UIScrollView和UIPageControl 作为子视图,创建3个UIImageView依次添加到UIScrollView中, 第一张图片显示数组中的最后一张图片,第二张图片显示数组中的第一张图片,第三张图片显示数组中的第二张图片,然后再让UIScrollView的偏移量为一个滚动视图的宽度offset.x = ScreenWidth, 这样用户看到的就是从图片的第一张开始看的,向左滑动看到第二张图片,向右滑动看到最后一张图片,这样的逻辑没毛病,这种逻辑和方式一的逻辑最大的不同是初始化时偏移了一个宽度(假如有7张图片)

这里写图片描述

当用户向左前进时此时,此时没有什么特殊之处,此时滚动视图会再偏移一个宽度,达到下面的状态

这里写图片描述

这种状态滚动结束之后如果不进行处理的话,用户就没法继续向左滚动了,因为已经滚动到头了,所以接下来要做特殊逻辑处理:

  • 偷偷替换3张图片:
    • 将中间的UIImageView0对应的图片换成当前屏幕上UIImageView1的图片images[1];
    • 将最后一个UIImageView1对应的图片换成UIImageView0对应的图片的下一张图片,即images[1];
    • 将第一个UIImageView2对应的图片换成当前屏幕显示的图片的上一张图片即images[0];
      这里写图片描述
  • 重置UIScrollView的偏移量为一个屏幕宽度offset.x = ScreenWidth;
    这里写图片描述

经过上述2个过程,用户又可以进行滚动了,向左向右滚动都没有问题

注意:这种逻辑有一个需要注意的地方就是当用户滚动临界点,比如滚动到最后一张用户还要往后滚动不能出现数组越界错误,下一张应该为第一张图片images[0],不能出现images[7],当用户滚动第一张时还要继续往前滚动也不能出现数组越界错误, 前面的图片应该为images[6],不能出现images[-1], 数组越界问题需要特殊的控制

这里写图片描述

这里写图片描述

该示例只分析了一直向左活动的操作,像右滑动的操作逻辑是和向左的完全一样的

github封装的图片无限轮播的自定义控件 https://github.com/mengday/XXImageLoopView


UICollectionView实现方式

方式二解决了UIScrollView没有重用机制的问题,而有重用机制的控件有UITableView和UICollectionView,而UITableView的滚动方向是垂直方向,可以通过对UITableView进行旋转90°,这样就可以水平方向了,但是UITableViewCell中的内容是反的,还要对内容再旋转90°更正方向,这样处理比较麻烦;而UICollectionView是支持水平方向的滚动的,所以UICollectionView即允许水平滚动又有重用机制,所以非常适合,唯一有个缺点是:UICollectionView是不支持无限轮播的,当滚动到头就不能再滚动了,为了实现无限轮播还需要特殊处理

  1. 增加图片数组的元素,将原始图片的最后一张插入到第0个位置,将原始图片的第0个元素追加到最后
    这里写图片描述

  2. 初始化时先便宜一个宽度来显示第一张图片
    这里写图片描述

  3. 当用户向右滚动到最前面状态时(图一),需要偷偷的立即将当前的偏移量定位到倒数第二个图片(图二),offset.x = CGPointMake((self.images.count - 1) * ScreenWidth,0), 这样一来用户就可以能向左滚动又可以向右滚动了
    这里写图片描述
    这里写图片描述

  4. 当用户向右滚动到最后一张图片时(图一),需要偷偷的立即将当前偏移量定位到正数第二个位置(图二),这样用户就又可以即可以向左滑动,又可以向右滑动。
    这里写图片描述

这里写图片描述


使用UICollectionView和使用UIScrollView的方式思想差不多

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
本Demo使用UICollectionView实现自动无限轮播功能。 主要功能: 1.实现自动轮播,可修改轮播的时间 2.轮播图片可以来自本地,也可来自网络,通过单独的方法进行设置即可。对于加载网络图片时,Demo中使用了YYWebImage,也可自行替换成SDWebImage。 3.重写了和系统UIPageControl一样的功能,可用图片代替PageControl上的点点,也可自定义其颜色以及切换动画。 使用方法:使用方法比较简单。 /** * 加载本地图片Banner */ - (void)setupLocalBannerImageView { NSArray *array = @[@"1.png", @"2.png", @"3.png", @"4.png", @"5.png"]; FFBannerView *bannerVew = [FFBannerView bannerViewWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 200) locationImageArray:array]; bannerVew.timeInterval = 2.0; [self.view addSubview:bannerVew]; } /** * 加载网络图片Banner */ - (void)setupNetWorkBannerImageView { NSArray *array = @[@"http://i3.download.fd.pchome.net/t_960x600/g1/M00/07/09/oYYBAFMv8q2IQHunACi90oB0OHIAABbUQAAXO4AKL3q706.jpg", @"http://images.weiphone.net/attachments/photo/Day_120308/118871_91f6133116504086ed1b82e0eb951.jpg", @"http://benyouhuifile.it168.com/forum/macos/attachments/month_1104/110425215921926a173e0f728e.jpg", @"http://benyouhuifile.it168.com/forum/macos/attachments/month_1104/1104241737046031b3a754f783.jpg"]; FFBannerView *bannerVew = [FFBannerView bannerViewWithFrame:CGRectMake(0, 250, [UIScreen mainScreen].bounds.size.width, 200) netWorkImageArray:array placeHolderImage:nil]; bannerVew.timeInterval = 2.0; bannerVew.pageControlStyle = FFPageControlStyleMiddle; bannerVew.delegate = self; [self.view addSubview:bannerVew]; } 以上方式即可简单使用,如需自定义PageControl也可继承FFAbstractDotView,做些基本的设置即可。 gitHub下载地址:喜欢的朋友请给个星呗! 欢迎各位一起来讨论,有问题请发邮箱270452746@qq.com或者直接加我QQ:270452746进行讨论。谢谢!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风流 少年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值