Swift实现轮播图以及自定义UIPageControl

轮播图.gif

无限轮播的实现思路

轮播图最核心的部分是如何实现无限轮播。我的实现方式是:

UIScrollView上添加三个UIImageView,要想达到无限轮播的效果,就要在任何停止滚动的时候(只展示一张完整图片的时候),scrollView.contentOffset.x 都应该等于轮播图宽度,即处于中间图片的位置,这样就能保证处在每一张图的位置时,左右都可以滑动。

代码的实现是,在 scrollViewDidScroll 代理方法中,判断当scrollView滚动到最左或者最右的极限位置时,立即将scrollView.contentOffset.x设置为轮播图宽度,即恢复到中间位置;

func scrollViewDidScroll(_ scrollView: UIScrollView) {
        let contentOffsetX = scrollView.contentOffset.x
        // 设置图片信息(滑到最左边或者最右边的时候,立即回正,同时改变图片,不会造成视觉上的误差)
        if contentOffsetX == 2 * scrollView.frame.width {// 左滑
            currentIndex = getActualCurrentPage(calculatedPage: currentIndex + 1)
            resetImageView()
        } else if (contentOffsetX == 0) {// 右滑
            currentIndex = getActualCurrentPage(calculatedPage: currentIndex - 1)
            resetImageView()
        }
}

同时,重新设置三张图的图片。这样在视觉效果上,就达到了无限滚动的效果。

fileprivate func resetImageView(){
        
        let preIndex: NSInteger = getActualCurrentPage(calculatedPage: currentIndex - 1)
        let nextIndex: NSInteger = getActualCurrentPage(calculatedPage: currentIndex + 1)
        
        if imageUrls.count == 0 {
            return
        }

        imageArray[0].sd_setImage(with: URL(string: imageUrls[preIndex]), placeholderImage: nil, options: [.refreshCached, .retryFailed])
        imageArray[1].sd_setImage(with: URL(string: imageUrls[currentIndex]), placeholderImage: nil, options: [.refreshCached, .retryFailed])
        imageArray[2].sd_setImage(with: URL(string: imageUrls[nextIndex]), placeholderImage: nil, options: [.refreshCached, .retryFailed])
        
        scrollNode.contentOffset = CGPoint(x: self.frame.width, y: 0)// 这里不可以使用setcontentOffset:animate的方法,否则滑动过快会出现bug
 }

 /// 根据下一页的计算值获取实际下一页的值
 ///
 /// - Parameter page: 通过+1或-1得到的下一页的值
 /// - Returns: 实际值
 fileprivate func getActualCurrentPage(calculatedPage page: NSInteger) -> NSInteger {
        if page == imageUrls.count {
            return 0
        } else if page == -1 {
            return imageUrls.count - 1
        } else {
            return page
        }
    }

自定义UIPageControl

类似于优酷的轮播图中的UIPageControl,实现起来比较简单,主要是通过改变原点的位置和长度,具体请参考Demo的代码。

github地址

你可能感兴趣的:(Swift实现轮播图以及自定义UIPageControl)