UIScrollView循环滑动

在iOS开发中,UIScrollView是不可以支持循环滚动的,但是越来越多的应用在头部都会有一个可以循环的Banner。本文就讲下如何在iOS实现这样的功能。

记得才开始编写iOS程序时,实现这个功能,我是通过判断scrollView是否滑动到最后,然后重新设置ContentOffset,滑到第一的位置。这样做需要加载所有的图片资源,有点浪费。这里提供一个新的解决方案。

首先我们初始化三个UIImageView,然后加载到UIScrollView上。

for i in 0..<3 {
    let imageView = UIImageView()
    imageView.isUserInteractionEnabled = true
    scrollView.addSubview(imageView)

    imageView.frame = CGRect(x: i * scrollView.width,
                                     y: 0,
                                     width: scrollView.width,
                                     height: scrollView.height)
}

scrollView.contentSize = CGSize(x: 3 * scrollView.widht, y: scrollView.height)

这里三个ImageView,设置第一个加载数据源最后一个图片,第二个加载数据源中第一张图片,第二个加载第二章图片。当滑动过后需要重新加载数据,这样向左向右滑动,看起来就是连续的,感觉scrollView可以循环了。当然在滑动时需要在scrollView的代理中做一些处理。

//当滑动结束时需要更新scrollView上的数据
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
        updateScroll()
}

func updateScroll() {
        let count = imageSource.count
        if count <= 1 {
            return
        }
        
        let offset = scrollView.contentOffset
        
        if offset.x > frame.width {
            currentIndex = (currentIndex + 1) % count
        } else if offset.x < frame.width {
            currentIndex = (currentIndex + count - 1) % count
        }
        
        //获取之前初始化的三个ImageView
        let leftImageView = imageViews[0]
        let centerImageView = imageViews[1]
        let rightImageView = imageViews[2]
        
        //替换ImageView上的图片
        let leftIndex = (currentIndex + count - 1) % count
        let rightIndex = (currentIndex + 1) % count
        
        
        reload(leftImageView, at: leftIndex)
        reload(centerImageView, at: currentIndex)
        reload(rightImageView, at: rightIndex)
        
        //此时图片替换成功后,但是scrollView已经滑动了,需要重新当前显示的ImageView永远为第二imageView
        //设置scrollView的contentOffset为第二个ImageView的位置
        scrollView.setContentOffset(CGPoint(x: scrollView.frame.width, y: 0), animated: false)
        pageControll.currentPage = currentIndex
    }

posted @ 2017-04-23 19:58  Lawerence  阅读(486)  评论(0编辑  收藏  举报