美文网首页swift首页投稿(暂停使用,暂停投稿)iOS Developer
Swift:两个UIImageView实现无限循环轮播(支持自动

Swift:两个UIImageView实现无限循环轮播(支持自动

作者: Hem1ngTai | 来源:发表于2016-08-15 18:49 被阅读871次

    这两年swift火得有点不像话,作为一个iOS开发者,Apple大大推出的编程语言是必须要学的,于是乎好多iOS攻城狮不是在用swift写项目就是在用swift改项目的路上。我着手的项目之前一直都是用纯OC编写的,因为项目较大,而且版本更新频率比较高,一直都没有转swift。趁着最近项目要发版本,手中的事不是很多,就开始试着写一个swift版本(论装逼的最高境界)。

    Swift发布以后,一直都是看文档,没怎么用swift写过项目,趁着这次机会尝试用swift写手中的项目。由于首页中就有无限轮播,自然着手点也从这开始。使用两个UIImageView+UIScrollView实现,二话不说,先看效果图:


    无限循环轮播.gif

    先说一下原理,这里假设图片的宽度为imgWidth,高度为imgHeight,scrollView的宽=图片的宽,scrollView的高=图片的高, 设置 scrollView 的 contentSize = 3倍图片宽度,高度相同,将第一个imageView放在scrollView的中间,第二个 imageView 放在最后,因为暂时不显示,所以放在最前面和最后面是一样的,再设置 scrollView 的偏移量为图片宽度(刚好显示中间的 imageView)。具体代码如下:

    //图片宽度
    imgWidth  = frame.size.width
    //图片高度
    imgHeight = frame.size.height
        
    scrollView = UIScrollView.init(frame: frame)
    scrollView?.delegate = self
    //设置分页
    scrollView?.pagingEnabled = true
    scrollView?.showsHorizontalScrollIndicator = false
    //设置 contentSize 为图片3倍宽度,高度相同
    scrollView?.contentSize = CGSizeMake(3*imgWidth!, imgHeight!)
    scrollView?.contentOffset = CGPointMake(imgWidth!, 0)
    self.addSubview(scrollView!)
        
    //将当前显示视图放在 scrollView 中间
    currentView = UIImageView.init(frame: CGRectMake(imgWidth!, 0, imgWidth!, imgHeight!))
    scrollView?.addSubview(currentView!)
        
    //下一视图放在中间视图后面
    nextView = UIImageView.init(frame: CGRectMake(2*imgWidth!, 0, imgWidth!, imgHeight!))
    scrollView?.addSubview(nextView!)
    

    上面设置完初始数据后,接下来就要定义一个变量 direction 来记录 scrollView 的滚动方向,这里我们先定义一个滚动方向枚举类型:

    enum Direction
    {
         case DirectionLeft     //向左滚动
         case DirectionRight    //向右滚动
         case DirectionNone     //无滚动
    }
    

    direction是记录 scrollView 的滚动方向的变量,它的值是根据滑动方向来改变的,所以要在 scrollView 中的代理方法监听 scrollView的滚动方向并赋值给direction。

    //MARK: -----UIScrollViewDelegate-----
    func scrollViewDidScroll(scrollView: UIScrollView)
    {
        let offsetX = scrollView.contentOffset.x;
        self.direction = offsetX > imgWidth! ? .DirectionLeft : offsetX < imgWidth! ? .DirectionRight : .DirectionNone
    }
    

    以前在 OC中我们可以用 KVO 来实现,但是 Swift 中没有 KVO,所以要想到重写 setter 方法来实现。

    var direction       :Direction = .DirectionNone  //滚动方向
    {
        //设置新值之前
        willSet
        {
            if newValue == direction
            {
                return
            }
        }
        //设置新值之后
        didSet
        {
            //向右滚动
            if direction == .DirectionRight
            {
                nextView?.frame = CGRectMake(0, 0, imgWidth!, imgHeight!)
                nextIndex = currentIndex!-1
                if nextIndex < 0
                {
                    nextIndex = (ADsArray?.count)! - 1
                }
            }
            //向左滚动
            if direction == .DirectionLeft
            {
                nextView?.frame = CGRectMake(imgWidth!*2, 0, imgWidth!, imgHeight!)
                nextIndex = (currentIndex!+1) % (ADsArray?.count)!
            }
            nextView?.backgroundColor = ADsArray![nextIndex!]
        }
    }
    

    上面代码可以看到,在滚动方向发生变化时我们要改变 nextView 的 frame,以及它对应的图片(这里因为是 demo,所以直接使用了color)。当滚动结束后 scrollView 会调用scrollViewDidEndDecelerating(scrollView: UIScrollView)这个方法,此时我们要改变currentView的 frame 以及它对应的图片(即 nextView 对应的图片)。

    let offset = self.scrollView!.contentOffset.x;
    let index = offset / self.imgWidth!
    //1表示没有滚动
    if index == 1
    {
         return
    }
    self.currentIndex = self.nextIndex
    self.pageControl?.currentPage = self.currentIndex!
    self.currentView?.frame = CGRectMake(self.imgWidth!, 0, self.imgWidth!, self.imgHeight!)
    self.currentView?.backgroundColor = self.nextView?.backgroundColor
    self.scrollView?.contentOffset = CGPointMake(imgWidth!, 0);
    

    关于自动轮播这里不再赘述,详情点击这里查看整个工程demo的实现,如有疑问和写的不好的地方还望各位多多包涵,也欢迎指正,如果对您确实产生了有利的影响也希望您能赏个star!!!

    相关文章

      网友评论

      • 羊驼先生丶:你使用的这个方法会有一个bug,就是在手动拖动的时候,如果托太快的话会出现卡住的情况,自动滚动的时候不会出现。可能是在拖动结束的代理里面实现的。托太快的话,上一次的拖动并没有结束。可以考虑使用uicollection来实现,就没有出现这样的bug。
        羊驼先生丶:@8badboy8 https://github.com/gsdios/SDCycleScrollView这个第三方库是使用的collectionview实现的,不过是oc代码。
        Hem1ngTai:@羊驼先生丶 好的,我试试看:smile:,感谢指正
      • 羊驼先生丶:朋友,你的地址无法访问了。能否给一下新的地址。十分感谢。
        羊驼先生丶:@8badboy8好的,谢谢了哈
        Hem1ngTai:@羊驼先生丶 不好意思,已经更新地址了,:smile:
        d9431116937e:兄弟别急,我去叫他
      • 羊驼先生丶:swift是有kvo的,但是仅限于NSobject的子类中。
      • d9431116937e:self.pageControl?.currentPage
        self.currentView?.frame
        self.currentView?.backgroundColor
        self.scrollView?.contentOffset
        这里为啥都是用的?
        d9431116937e:@羊驼先生丶 可以
        羊驼先生丶:他声明的时候用的可选型。

      本文标题:Swift:两个UIImageView实现无限循环轮播(支持自动

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