美文网首页iOSiOSswift
iOS简易轮播图的实现

iOS简易轮播图的实现

作者: VSCCW | 来源:发表于2016-07-30 19:43 被阅读1612次

前言

见过很多的iOS应用,都有无限轮播图,之前也看到过很多相关实现的文章,可是仅仅就是一看而过罢了。当自己在项目中用到这个,真正去写的时候才发现不是很容易,遇到了一些问题,这篇文章就记录下自己最后成功实现轮播图的历程。

原理

原理其实就是一种假象。不过在我这里,目前有过两种原理的实现。一种利用UICollectionView实现轮播,另一种利用UIScrollView实现轮播。
今天我们要来打造一款这样的轮播图(图画的不好,请勿见怪)。

举例:三张图的无限轮播

原理一:利用UIScrollView实现轮播图。

要想实现这样的效果,我们使用UIScrollView包含image0,image1,image2的三个UIImageView都是放在UIScrollView里面的,但是这样的话是不可以实现轮播的。要想实现轮播就要再在该UIScrollView的左右两侧各加一张UIImageView。在最后一张放image0, 第一张放image2。这样的话当我们滚动到最后或者最前面的的时候,我们就把列表切换到相应的位置。

实际UISrollView图

原理二:利用UICollectionView实现轮播图。

你当然可以利用原理一再用UICollectionView实现一次。但是我这里采用一种偷懒的方式,利用UICollectionView的cell重用机制。创建个无数个cell,比如3x20000。当用户第一次进来的我们就将UICollectionView滑到3x20000x0.5的位置。然后利用cell.indexPath.item % 3来对cell上的UIImageView进行image显示。这种方式比较偷懒,在后来添加NSTimer自动轮播和点击事件的时候也比较简单,不过有点大炮打小鸟的感觉。所以我在这里也只是介绍下原理,如果你有兴趣,可以自己尝试去实现下。而且UICollectionView自带一个方法- scrollToItemAtIndexPath:atScrollPosition:animated:还比较厉害。

具体实现

针对原理一,我就来简单实现下。(我这里使用代码创建,你也可以使用Storyboard创建,原理一样)

创建工程,创建BannerView.Swift,添加初始化代码如下:

/// 初始化scrollView
lazy var scrollView: UIScrollView = {
       let scrollView = UIScrollView()
       scrollView.delegate = self
       scrollView.alwaysBounceVertical = false
       scrollView.bounces = true
       scrollView.pagingEnabled = true
       scrollView.scrollEnabled = true
       scrollView.showsVerticalScrollIndicator = false
       scrollView.showsHorizontalScrollIndicator = false
       return scrollView
   }()
/// 初始化pageControl
   lazy var pageControl: UIPageControl = {
       let pageControl = UIPageControl()
       pageControl.currentPageIndicatorTintColor = UIColor.redColor()
       pageControl.pageIndicatorTintColor = UIColor.whiteColor()
       return pageControl
   }()

   /// 在init里调用setupSubviews即可
   func setupSubviews() {  
       self.addSubview(scrollView)
       self.addSubview(pageControl)

       scrollView.translatesAutoresizingMaskIntoConstraints = false
       pageControl.translatesAutoresizingMaskIntoConstraints = false

       self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[v]|", options: [], metrics: nil, views: ["v": scrollView]))
       self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[v]|", options: [], metrics: nil, views: ["v": scrollView]))

       self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:[p(==20)]-10-|", options: [], metrics: nil, views: ["p": pageControl]))
       self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:[p(==100)]-10-|", options: [], metrics: nil, views: ["p": pageControl]))
   }

初始化UIScrollView:

func setupScrollView() {
        /// 创建 (imageNames.count + 2)个UIImageView
        for index in 0 ... (imageNmaes.count + 1) {
            let imageView = UIImageView(frame: CGRect(x: self.width*CGFloat(index), y: 0, width: self.width, height: self.height))
            var picName = String()
            switch index {
            case 0:
                picName = imageNames[imageNames.count-1]
                break
            case imageNames.count + 1:
                picName = imageNames[0]
                break
            default:
                picName = imageNames[index-1]
                break
            }

//          imageView.af_setImageWithURL(NSURL(string: picName)!)
            imageView.image = UIImage(named: picName)
            imageView.contentMode = .ScaleToFill
            imageView.clipsToBounds = true
            imageView.userInteractionEnabled = true
            scrollView.addSubview(imageView)
        }
        scrollView.contentSize = CGSize(width: self.width * CGFloat(imageNames.count + 2), height: self.height)
        scrollView.contentOffset = CGPoint(x: self.width, y: 0)
    }

无限轮番的实现。(重点)使用UIScrollViewDelegate协议。

func scrollViewDidScroll(scrollView: UIScrollView) {
       if scrollView == self.scrollView {
           let contentOffsetX = scrollView.contentOffset.x
          ///向前滑动到第0张图的时候,滚到第三张图
           if contentOffsetX == 0 {
               scrollView.contentOffset = CGPoint(x: self.width * CGFloat(self.imageNames.count), y: 0)
           }
           /// 跑到第三张图的时候,滚到第0张图
           if contentOffsetX == CGFloat(self.imageNames.count + 1)*self.width {
               scrollView.contentOffset = CGPoint(x: self.width, y: 0)
           }
           /// 改变pageControl,这里要注意,一定要一定要一定要 - 0.5, 因为最前面的第0张图一直不显示。
           let index = scrollView.contentOffset.x / self.width - 0.5
           self.pageControl.currentPage = Int(index)
       }
   }

添加计时器

好了,做到这里,你已经成功实现了轮播图,可是这个轮播图是手动的,下面添加自动滚动。也很简单,设置一个NSTimer计时器即可。代码如下:

// MARK: - Timer
   var timer: NSTimer?
   var i = 1
   /// 在scrollView上的图片成功设置后调用startTimer即可
   private func startTimer() {
       if timer != nil {
           self.stopTimer()
       }
       /// 这里设置的滚动间隔为2秒
       timer = NSTimer.scheduledTimerWithTimeInterval(2, target: self, selector: #selector(autoScroll), userInfo: nil, repeats: true)
       NSRunLoop.currentRunLoop().addTimer(timer!, forMode: NSDefaultRunLoopMode)
   }
   private func stopTimer() {
       timer?.invalidate()
       timer = nil
   }
   func autoScroll() {
       if i == imageNames.count + 1 {
           i = 1
       }
       i += 1
       /// 在处理无限轮番的时候设置contentOffset没有添加animated,这里要添加上来,不然有种很突兀的感觉。
       scrollView.setContentOffset(CGPoint(x: self.width * CGFloat(i), y: 0), animated: true)
   }
    /// 手动滚动结束后恢复计时
   func scrollViewDidEndDragging(scrollView: UIScrollView, willDecelerate decelerate: Bool) {
        self.startTimer()
    }
    /// 当手动滚动开始时停止计时
    func scrollViewWillBeginDragging(scrollView: UIScrollView) {
        self.stopTimer()
    }

添加具体点击事件

具体到点击事件的话,我是放在初始化imageView那里处理的,给imageVIew添加一个UITapGestureRecognizer,在这里最好再写一个代理方法,将imageView的点击事件传递出去。然后根据当前contentOffet.x / self.width来将具体哪张图片的事件传递出去。我就不用代码展示了。

结尾

还是比较简单的。但是我这个复用性比较差,封装的也不好,可是具体要看思路😂。代码实现放在了Github Wiki上了BannerView.Swift,由于工程量太小,就没将工程文件上传了。

关于作者

Qiuncheng,一位正在iOS路上前行的初学者,正在努力成为一名合格的iOS开发者。

相关文章

  • iOS简易轮播图的实现

    前言 见过很多的iOS应用,都有无限轮播图,之前也看到过很多相关实现的文章,可是仅仅就是一看而过罢了。当自己在项目...

  • iOS功能技术索引

    1.iOS上简易轮播图的实现 2.自定义UICollection View,这篇文章来自ObjC中国 3.moda...

  • 三种样式的轮播图

    一、100%比例轮播图 HTML代码 CSS样式 js代码 二、手动箭头轮播图 三、简易轮播图

  • React 实现简易轮播图

    使用 ReactJS 实现一个简易的轮播图 (carousel) 组件。 Task 1:在相框中展示图片,左右按钮...

  • swift第三方控件

    iOS开发:Swift实现的轮播图、无限循环视图控件CYCircularScrollView CycleScrol...

  • 小程序利用swiper实现轮播图

    小程序实现轮播图比iOS简单很多 .wxml代码: .wxss代码: .js代码:

  • iOS高效图片轮播 - 两个imageView实现

    iOS高效图片轮播 - 两个imageView实现 iOS高效图片轮播 - 两个imageView实现

  • 造轮子系列--撸一个轮播图

    PictureCarousel 先上效果图: 可以看到,我们实现了一个简易的图片轮播器。下面我们从设计到实现一步一...

  • 轮播图心得

    轮播图 写轮播图之前我们要认识到几个问题:一、什么是轮播图?二、怎么实现轮播效果?三、轮播图还有什么小功能可以实现...

  • 简易轮播图实现——乞丐版

    前几天刚学到了一种最简单的轮播图实现方法,现在写在博客里就当是练习了。。。这种方法的核心原理是通过给图片元素附加d...

网友评论

  • c57dddf3b833:写得很赞啊,原理二的我也分享一个我们一直在用的Github的库 http://dwz.cn/3SosVV 。一句话调用
    c57dddf3b833:@江湖丽日 代码是开源的,基于UICollectionView做的,流畅调用又相当简单,可以试试
    af4e8a35bc89:@c57dd 关于轮播图 我没太用过第三方 ,回头我找个时间分析一下你上边说的库
    VSCCW:@c57dd 嗯嗯。这个好。😀
  • 071a958d5815:喜欢
    VSCCW:@071a958d5815 嗯嗯:grin:

本文标题:iOS简易轮播图的实现

本文链接:https://www.haomeiwen.com/subject/zajtsttx.html