iOS开发之三个Button实现图片无限轮播(参考手机淘宝,Swift版)

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
查看查看336 回复回复2 收藏收藏 分享淘帖 转播转播 分享分享 微信
查看: 336|回复: 2
收起左侧

iOS开发之三个Button实现图片无限轮播(参考手机淘宝,Swift版)

[复制链接]
swifter 发表于 2016-7-20 17:11:04 | 显示全部楼层 |阅读模式
快来登录
获取优质的苹果资讯内容
收藏热门的iOS等技术干货
拷贝下载Swift Demo源代码
订阅梳理好了的知识点专辑

这两天使用Reveal工具查看"手机淘宝"App的UI层次时,发现其图片轮播使用了三个UIButton的复用来实现的图片循环无缝滚动。于是乎就有了今天这篇博客,看到“手机淘宝”这个幻灯片的UI层级时,就想要动手使用三个Button来实现一下,当然本篇博客使用是Swift语言,思路就是使用三个Button进行图片无限轮播。之前发过两篇关于图片轮播的博客,一个是没有使用ImageView复用的,一个是使用两张ImageView进行复用来实现图片轮播的,都是使用的Objective-C实现的,并在github上进行了代码分享。

本篇博客就是介绍如何去一步步的封装这个三个Button的无限轮播的组件的。在实现时将该无限轮播的组件进行了封装,需要你在实例化该组件后,传入一个存放图片地址的数组,数组中可以是本地图片的名字,也可以是一个网络图片的地址。如果是网络图片的地址,组件中会使用NSRULSession并采用合适的缓存策略从网络加载图片,加载完后在我们的组件上进行显示。废话少说,进入我们今天的主题。

今天的博客完全是个人兴趣爱好,也不是公司中项目要使用的缘故才去实现的。就是看到了淘宝中的轮播图,从UI层级上感觉这样可以实现,于是乎就打开Xcode,创建个Swift工程实现一把,过程还是蛮愉快的。当然今天封装组件的名称是以公司的名称首字母做的前缀了,这也便于在以后的工作中遇到该问题直接拿过来就用呢。




1、对“手机淘宝”UI层次的简单分析

下方截图就是当时我用Reveal工具查看的手机淘宝App的UI层级,下方只是幻灯片的部分。下方整个页面是使用UICollectionView来实现的了,下方的幻灯片所在的UIScrollView就放在UICollectionView上的一个Cell上。当然这不是我们今天的重点,我们将目光转移到左边红框中的数学层级上。可以明显的看出UIScrollView上贴了三个UIButton,而每个UIButton上又贴了一个UIImageView

需要注意的一点是你看到UIButton是三个Button的中间一个,从下面UI视图中我们不难分析出,无论当前显示的是第几张图片,你看到的永远是中间Button上显示的图片。也就是将要显示的图片放到中间的Button上,左边的Button存放上一张图片,右边的Button存放下一张图片。当用户左划或者右划后,我们要做的事情就是将中间按钮放到可视区,并且设置成要显示的图片,当然左右两个Button都得设置成相应的图片,便于用户下次移动。当然这只是我的个人猜测,上面这种思路使用代码来实现是完全可行的,并且可以实现无循环无缝滚动了。

当然,上面说的原理比较简单,具体使用代码实现起来还是需要许多细节的。比如用户滑动时定时器的挂起和唤醒,用户左右滑动方向的记录,便于自动轮播时的方向与用户上次滑动的方向一致,异步加载网络请求图片,加载后显示在相应的Button上,通过Closure回调出用户点击事件可当前图片的索引信息等等需要注意的细节。敲代码也有几年时间了,有一点感触挺深的就是“说和做”完全是两码事,也就是你有思路和你把你的思路用代码实现,这是完全不同的概念。当然正确的思路固然重要,但是不去实现再好的思路也是枉费,实践出真知吗。说这么多,有回到了说与做的问题上,这话题就不多讨论了,高执行力,高自制力好处是多多的。言归正传,回到今天的主题。

iOS开发之三个Button实现图片无限轮播(参考手机淘宝,Swift版) 1

iOS开发之三个Button实现图片无限轮播(参考手机淘宝,Swift版) - 敏捷大拇指 - iOS开发之三个Button实现图片无限轮播(参考手机淘宝,Swift版) 1





2、从“原理图”中来看今天轮播的主题

下方就是今天要实现的轮播组件的原理图,思路就是这么个思路,要实现起来还得靠代码往上摞呢。下方解析图是以轮播5张图片为例。初始化状态是你看到的是第一张图片,第一张图片位于三个Button的中间,然后左边就是最后一张图片,右边是第二张图片。如果用户想右滑动显示的第二张图片(对应着下方的第一步),当第二张图片已经完全显示出来后,我们要做的第一件事情就是将用户移动的位置进行复位,也就是将第二个Button移动到显示的位置,然后设置按钮上显示相应的图片。第一个按钮就显示当前图片的前一张图片,如果当前显示的是第一张图片,那么第一个按钮上就显示最后一张图片。第三个按钮就显示当前图片的下一张图片,如果当前显示的图片是最后一张图片的话,那么第三个按钮上就显示第一张图片。这样就可以图片轮播了。

iOS开发之三个Button实现图片无限轮播(参考手机淘宝,Swift版) 2

iOS开发之三个Button实现图片无限轮播(参考手机淘宝,Swift版) - 敏捷大拇指 - iOS开发之三个Button实现图片无限轮播(参考手机淘宝,Swift版) 2





3、该自定义控件的视图层级

下图就是我们按照上面的思路,使用ScrollView上添加3个Button来实现的图片轮播,无缝滚动的效果还是蛮OK的。在下方运行效果中美女图片是从本地加载的,而风景图片是使用NSURLSession和GCD的东西并行异步的从网络获取的,获取完后再加载到相应Button的ImageView上。下方就是我们本篇博客相关Demo的运行效果,单从效果上来看,与之前所发布的图片轮播没有什么区别,但是其内部实现机制还是有较大区别的。接下来就逐步的看一下代码实现。

iOS开发之三个Button实现图片无限轮播(参考手机淘宝,Swift版) 3

iOS开发之三个Button实现图片无限轮播(参考手机淘宝,Swift版) - 敏捷大拇指 - iOS开发之三个Button实现图片无限轮播(参考手机淘宝,Swift版) 3


上面是运行效果,下方是UI的层级。当然也是用我们强大的Reveal来查看的了,下方红框中就是我们图片轮播的视图层级。该视图层级与“手机淘宝”上是一致的,都是在UIScrollView上贴了三个Button,然后在每个Button上贴了一个ImageView。层级比较简单,而你看到的当然是中间Button上的ImageView了,更多细节请看下图。

iOS开发之三个Button实现图片无限轮播(参考手机淘宝,Swift版) 4

iOS开发之三个Button实现图片无限轮播(参考手机淘宝,Swift版) - 敏捷大拇指 - iOS开发之三个Button实现图片无限轮播(参考手机淘宝,Swift版) 4





4、代码实现

运行效果看完了,UI层级结构也看完了,那么接下来就到了我们代码实现的时刻了。下方从组件的调用方式入手,逐步的去看一下上述效果是如何实现的。



4.1、上述组件的调用方式

下方代码段就是上述组件的实例化和调用方式,首先进行初始化,然后将该组件添加到父视图上。之后将要显示的图片数组imagesNameArray传入组件中,最后设置一下组件的闭包回调即可,该回调将每个按钮点击的时间回调给组件的使用者,该Closure的参数是当前点击按钮上所显示的Image的索引,说白了也就是你当前点击的第几张图片。

iOS开发之三个Button实现图片无限轮播(参考手机淘宝,Swift版) 5

iOS开发之三个Button实现图片无限轮播(参考手机淘宝,Swift版) - 敏捷大拇指 - iOS开发之三个Button实现图片无限轮播(参考手机淘宝,Swift版) 5


在调用组件时,传入给组件的参数是一个数组,下方代码就是我们初始化imagesNameArray的函数。从该代码段中我们不难看出,该数组中存储的有本地图片的名字,也有UIImage的对象,也有网络图片的URL。将含有三种元素的数组传给我们的组件实例,这些数组中的资源就可以按照数组中的顺序依次的循环轮播了。

iOS开发之三个Button实现图片无限轮播(参考手机淘宝,Swift版) 6

iOS开发之三个Button实现图片无限轮播(参考手机淘宝,Swift版) - 敏捷大拇指 - iOS开发之三个Button实现图片无限轮播(参考手机淘宝,Swift版) 6




4.2、上述组件的核心代码

组件调用方式还是蛮简单的,看完调用方式,接下来来看一下具体的代码实现。下方是我们组件中比较核心的实现部分。


4.2.1、异步加载网络图片

下方代码段就是遍历我们的ImagesNameArray,找出该数组中所有的网络图片的URL,每找到一个URL就开启一个线程来请求该地址中的图片。下方的queue是并行队列,此处当然是并行队列的异步执行了。关于GCD的东西,请参考之前的博客《Grand Central Dispatch详解》。

iOS开发之三个Button实现图片无限轮播(参考手机淘宝,Swift版) 7

iOS开发之三个Button实现图片无限轮播(参考手机淘宝,Swift版) - 敏捷大拇指 - iOS开发之三个Button实现图片无限轮播(参考手机淘宝,Swift版) 7


下方代码段就是requestImage()方法中的内容了,该方法中使用NSSession并配置相应的缓存策略来请求网络图片。加载完图片后,将ImagesNameArray中相应的URL替换成相应的UIImage对象,然后在主线程中更新UI显示相应的图片,具体代码如下所示。

iOS开发之三个Button实现图片无限轮播(参考手机淘宝,Swift版) 8

iOS开发之三个Button实现图片无限轮播(参考手机淘宝,Swift版) - 敏捷大拇指 - iOS开发之三个Button实现图片无限轮播(参考手机淘宝,Swift版) 8



4.2.2、moveImageView()方法的实现

该方法负责将按钮归位与赋值,该方法对应着上述原理图的第二和第三步。上面网络请求完一张图片后就会调用该方法更新UI。该方法的具体实现如下所示。下方代码中首先获取当前显示的页数,也就是当前显示的Image的索引,然后将第二个Button移动到可视区,最后调用setButtonImage()函数将每个Button上的ImageView设置成相应的Image。

iOS开发之三个Button实现图片无限轮播(参考手机淘宝,Swift版) 9

iOS开发之三个Button实现图片无限轮播(参考手机淘宝,Swift版) - 敏捷大拇指 - iOS开发之三个Button实现图片无限轮播(参考手机淘宝,Swift版) 9



4.2.3、定时器的实现

图片要隔段时间自动轮播,此处我们使用的是dispatch_source中的定时器类型来实现的自动轮播。下方就是我们定时器的实现,如下所示,代码比较简单,在此就不做过多的赘述了,创建完定时器我们不要忘了对定时器的source进行唤醒即可。

iOS开发之三个Button实现图片无限轮播(参考手机淘宝,Swift版) 10

iOS开发之三个Button实现图片无限轮播(参考手机淘宝,Swift版) - 敏捷大拇指 - iOS开发之三个Button实现图片无限轮播(参考手机淘宝,Swift版) 10


当用户进行手动切换时,我们要对定时器进行相应的挂起和唤醒操作。也就是说当用户开始滑动时我们要对定时器进行挂起,当用户滑动结束后要对定时器进行唤醒。当然这些都是在ScrollView相应的代理方法中进行处理的,具体如下所示:

iOS开发之三个Button实现图片无限轮播(参考手机淘宝,Swift版) 11

iOS开发之三个Button实现图片无限轮播(参考手机淘宝,Swift版) - 敏捷大拇指 - iOS开发之三个Button实现图片无限轮播(参考手机淘宝,Swift版) 11



4.2.4、滑动结束后更新按钮的位置和图片

无论是手动滑动,还是使用定时器滑动,滑动结束后我们都需要更新一下按钮的位置和按钮上要显示的图片。所以我们还需要使用到UIScrollView上的一个代理方法,那就是scrollViewDidScroll(),在该代理方法中我们调用了moveImage()方法来更新Button的位置和Button上ImageView要显示的图片信息。没有这个方法,图片就动不起来了,具体代码如下所示:

iOS开发之三个Button实现图片无限轮播(参考手机淘宝,Swift版) 12

iOS开发之三个Button实现图片无限轮播(参考手机淘宝,Swift版) - 敏捷大拇指 - iOS开发之三个Button实现图片无限轮播(参考手机淘宝,Swift版) 12



上述是该Demo的核心代码,更为详细的代码请移步于github: http://github.com/lizelu/CEImagesScrollDisplay,因本篇博客篇幅有限,更具体的细节在此就不做过多赘述了,Demo已在上述github上进行分享。




作者:青玉伏案

都看到这里了,就把这篇资料推荐给您的好朋友吧,让他们也感受一下。

回帖是一种美德,也是对楼主发帖的尊重和支持。您的赞赏是我前进的方向。

*声明:敏捷大拇指是全球最大的Swift开发者社区、苹果粉丝家园、智能移动门户,所载内容仅限于传递更多最新信息,并不意味赞同其观点或证实其描述;内容仅供参考,并非绝对正确的建议。本站不对上述信息的真实性、合法性、完整性做出保证;转载请注明来源并加上本站链接,敏捷大拇指将保留所有法律权益。如有疑问或建议,邮件至marketing@swifthumb.com

*联系:微信公众平台:“swifthumb” / 腾讯微博:@swifthumb / 新浪微博:@swifthumb / 官方QQ一群:343549891(满) / 官方QQ二群:245285613 ,需要报上用户名才会被同意进群,请先注册敏捷大拇指

评分

参与人数 1金钱 +10 贡献 +10 专家分 +10 收起 理由
Anewczs + 10 + 10 + 10 32个赞!专家给力!

查看全部评分

本帖被以下淘专辑推荐:

攻城狮 发表于 2016-7-20 21:32:59 | 显示全部楼层
无限?考虑过性能问题么?
苏格拉没有底 发表于 2016-7-21 03:45:24 | 显示全部楼层
终于看完~ 谢谢楼主
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

淘帖专辑
我要发帖

分享扩散

都看到这里了,就把这资料推荐给您的好朋友吧,让他们也感受一下。
您的每一位朋友访问此永久链接后,您都将获得相应的金钱积分奖励
热门推荐

合作伙伴

Swift小苹果

  • 北京治世天下科技有限公司
  • ©2014-2016 敏捷大拇指
  • 京ICP备14029482号
  • Powered by Discuz! X3.1 Licensed
  • swifthumb Wechat Code
  •   
快速回复 返回顶部 返回列表