技术头条 - 一个快速在微博传播文章的方式     搜索本站
您现在的位置首页 --> iOS开发 --> iOS下自己动手造无限循环图片轮播

iOS下自己动手造无限循环图片轮播

浏览:1526次  出处信息

   代码示例:https://github.com/johnlui/Swift-On-iOS/tree/master/BuildAnInfiniteCarousel/BuildAnInfiniteCarousel

   环境要求:Xcode 7.0+ / Swift 2.0+

   本篇文章中,我将跟大家一起动手构造一个非常常见的无限循环的图片轮播功能。

目标

   我们的目标是打造一个支付宝这样的无限循环图片轮播:图片占满屏幕宽度,底部居中有小点点指示位置。

   pic

搭建界面

准备工作

   新建一个名为 BuildAnInfiniteCarousel 的单页面项目,拖进去四张尺寸一样的素材图片,下面我们开始搭建页面。

添加 Scroll View

   拖动一个 Scroll View 添加到页面顶端,设置宽高比为 2:1,使用 Auto Layout 确定其位置:

   pic

   勾选掉“显示滚动条”,勾选上 Paging Enabled 以实现自动停靠:

   pic

添加 Page Control

   拖动一个 Page Control 组件添加到页面上,悬浮到 Scroll View 上方,此处的 Auto Layout 约束大家自由发挥。将 Page Control 的 pages 总数设置为 4。

实现思路

无限轮播

   无限轮播其实只是一个欺骗。如果我们有四张图片需要显示,编号1、2、3、4,那么我们只需要放上四张图片,再在前面放一张 4 号图,在最后放一张 1 号图,在用户滚动到最前或者最后的时候,不声不响地将列表回滚到中间的 1、4 号图,在用户看来是一直在朝一个方向滚动,实际上在中间我们神不知鬼不觉的把列表往回滚到了特定位置。

指示位置的小点点

   这个很容易想到,使用 Scroll View Delegate,检测滚动距离,改变 currentPage 即可。

开始编码

绑定 UI 元素到 View Controller

   分别右键(或者按住 Ctrl)绑定 Scroll View 和 Page Control 到 View Controller,此处不再上图。

插入图片

   我们先做有限的图片轮播。在 viewDidLoad 中使用代码给 Scroll View 插入四张图片:

let width = UIScreen.mainScreen().bounds.width
let height = width/2

for i in 0...3 {
   let iv = UIImageView(frame: CGRectMake(width * CGFloat(i), 0, width, height))
   iv.image = UIImage(named: "pic\(i+1)")
   iv.contentMode = UIViewContentMode.ScaleAspectFill
   iv.clipsToBounds = true
   iv.userInteractionEnabled = true
   self.scrollView.addSubview(iv)
}
self.scrollView.contentSize = CGSizeMake(width * 4, height)

   运行,此时已经得到了可以自动停靠的四张图片的轮播了。

指示位置的小点点联动

   根据上面提到的思路,使用以下代码实时计算小点点的 currentPage:

class ViewController: UIViewController, UIScrollViewDelegate {
... ...
func scrollViewDidScroll(scrollView: UIScrollView) {
   if scrollView == self.scrollView {
       let currentPage = scrollView.contentOffset.x / UIScreen.mainScreen().bounds.width + 0.5
       self.pageControl.currentPage = Int(currentPage)
   }
}

   建议采用以前分享过的 可视化方法 将 Scroll View 的 delegate 设置成当前 View Controller。

   至此,有限图片轮播已经完成。

跨越到无限轮播

增加第 0 张和第 5 张图片

   增加 for 循环的上限到 5,修改图片加载逻辑,给 Scroll View 设置一个初始的 offset 值:

for i in 0...5 {
   let iv = UIImageView(frame: CGRectMake(width * CGFloat(i), 0, width, height))
   var picName = "pic"
   switch i {
   case 0:
       picName += "4"
   case 5:
       picName += "1"
   default:
       picName += i.description
   }
   iv.image = UIImage(named: picName)
   iv.contentMode = UIViewContentMode.ScaleAspectFill
   iv.clipsToBounds = true
   iv.userInteractionEnabled = true
   self.scrollView.addSubview(iv)
}
self.scrollView.contentSize = CGSizeMake(width * 6, height)
self.scrollView.contentOffset = CGPointMake(width, 0)

不声不响地滚动

   同样是在 scrollViewDidScroll 里面操作:

func scrollViewDidScroll(scrollView: UIScrollView) {
   if scrollView == self.scrollView {
       let width = UIScreen.mainScreen().bounds.width
       let offsetX = scrollView.contentOffset.x
       
       if offsetX == 0 {
           scrollView.contentOffset = CGPointMake(width * CGFloat(4), 0)
       }
       if offsetX == width * CGFloat(4 + 1) {
           scrollView.contentOffset = CGPointMake(width, 0)
       }
       
       let currentPage = scrollView.contentOffset.x / width + 0.5
       self.pageControl.currentPage = Int(currentPage)
   }
}

解决小点点错了一位的问题

   将 + 0.5 改成 - 0.5 即可:

let currentPage = scrollView.contentOffset.x / width - 0.5

搞定!

查看成果

   pic

后话

   如果需要复用,单独用 xib 或者 StoryBoard 实现即可,思路完全一致。

建议继续学习:

  1. 在C++中实现foreach循环,比for_each更简洁!    (阅读:8497)
  2. for 循环为何可恨?    (阅读:4330)
  3. 循环、迭代、遍历和递归    (阅读:4305)
  4. C/C++循环获取文件中的每行数据(别以为很简单!)    (阅读:3731)
  5. 优化次数过多的循环    (阅读:2537)
  6. 图片轮播控件 Carousel Controls    (阅读:2426)
  7. 数组的优化循环展开与分割    (阅读:2362)
  8. Loop Benchmarks    (阅读:2197)
  9. 网站广告投放策略研究 (一) 轮播以及效用最大化    (阅读:2056)
  10. Perl6有用的和有意思的循环    (阅读:1846)
QQ技术交流群:445447336,欢迎加入!
扫一扫订阅我的微信号:IT技术博客大学习
© 2009 - 2024 by blogread.cn 微博:@IT技术博客大学习

京ICP备15002552号-1