博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Swift 无限轮播图
阅读量:6932 次
发布时间:2019-06-27

本文共 6708 字,大约阅读时间需要 22 分钟。

ICycleView

ICycleView是一个基于UICollectionView实现的轻量级无限轮播图

效果图

Content

  • [Features]()
  • [Requirements]()
  • [CocoaPods]()
  • [Usage]()

    • [默认滚动视图]()
    • [自定义图片宽度和指示器的位置和颜色]()
    • [自定义Cell-纯代码和Xib创建都支持]()
  • [Implementation]()

    • [实现原理]()
    • [主要代码]()

      • [UICollectionView代理方法]()
      • [循环轮播实现]()
  • [Contact]()
  • [Github]()

Features

  • 支持单张图片
  • 支持滚动图片宽度设置
  • 支持本地图片显示,网路图显示,本地图片和网路图混合显示
  • 支持自定义图片展示Cell(纯代码和Xib创建都支持)
  • 支持UIPageControl具体位置设置
  • 支持UIPageControl显示颜色设置
  • 支持图片点击回调
  • 支持图片滚动回调

Requirements

  • iOS 8.0+
  • Swift 4.0+

pod 'ICycleView', '~> 1.0.0'

在终端 pod search 'ICycleView' 时若出现 Unable to find a pod with name, author, summary, or description matching 'ICycleView' 错误

请在终端运行
1:pod setup
2:$rm ~/Library/Caches/CocoaPods/search_index.json

Usage

默认滚动视图

效果图

// 惰性初始化滚动视图lazy var defaultCycleView: ICycleView = {    let cycleView = ICycleView(frame: CGRect(x: 0, y: 50, width: UIScreen.main.bounds.width, height: 130*scaleForPlus))    view.addSubview(cycleView)    return cycleView}()// 图片赋值defaultCycleView.pictures = pictures
自定义图片宽度和指示器的位置和颜色

效果图

// 惰性初始化滚动视图lazy var customPagetrolPositionnCycleView: ICycleView = {    let cycleView = ICycleView(frame: CGRect(x: 0, y: 190, width: UIScreen.main.bounds.width, height: 130*scaleForPlus))    cycleView.imgViewWidth = 374*scaleForPlus    cycleView.pageIndicatorTintColor = .green    view.addSubview(cycleView)    return cycleView}()// 图片赋值customPagetrolPositionnCycleView.pictures = pictures// pageControlStyle属性必须在设置 pictures 后赋值,因为指示器是根据 numberOfPages 计算Size的customPagetrolPositionnCycleView.pageControlStyle = .bottom(bottom: -20)customPagetrolPositionnCycleView.pageControlStyle = .right(trailing: 30*scaleForPlus)
自定义Cell-纯代码和Xib创建都支持

效果图

// 惰性初始化滚动视图lazy var customPictureCellCycleView: ICycleView = {    let cycleView = ICycleView(frame: CGRect(x: 0, y: 345, width: UIScreen.main.bounds.width, height: 130*scaleForPlus))    cycleView.register([UINib.init(nibName: "CustomCycleViewCell", bundle: nil)], identifiers: ["CustomCell"])    cycleView.delegate = self    view.addSubview(cycleView)    return cycleView}()// 图片赋值customPictureCellCycleView.pictures = pictures// 代理方法/** - 协议方法都是可选方法,根据需要实现即可 */// MARK: ICycleViewDelegateextension ViewController: ICycleViewDelegate {    // 图片点击    func iCycleView(cycleView: ICycleView, didSelectItemAt index: Int) {        print("你点击了第 \(index) 张图片")    }    // 图片自动滚动    func iCycleView(cycleView: ICycleView, autoScrollingItemAt index: Int) {        print("当前滚动的图片是第 \(index) 张")    }    // 自定义Cell    func iCycleView(cycleView: ICycleView, collectionView: UICollectionView, cellForItemAt indexPath: IndexPath, picture: String) -> UICollectionViewCell {        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CustomCell", for: indexPath) as! CustomCycleViewCell        cell.imgView.kf.setImage(with: URL(string: picture))        cell.titleLab.text = "自定义Cell\n第 \(indexPath.item) 张图片"        return cell    }}

Implementation

实现原理
  1. collectionView的cell显示两倍数量的图片,展示图片分为两组,默认显示第二组的第一张
  2. 左滑collectionView到第二组最后一张,即最后一个cell时,设置scrollView的contentOffset显示第一组的最后一张,继续左滑,实现了无限左滑
  3. 右滑collectionView到第一组第一张,即第一cell时,设置scrollView的contentOffset显示第二组的第一张,继续右滑,实现了无限右滑
  4. 由2,3实现无限循环
主要代码
UICollectionView代理方法
// MARK: - UICollectionViewDataSource, UICollectionViewDelegateextension ICycleView: UICollectionViewDataSource, UICollectionViewDelegate {        public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {        return pictures.count * 2    }        public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {                if isCustomCell {            // 自定义Cell            return delegate?.iCycleView?(cycleView: self, collectionView: collectionView, cellForItemAt: IndexPath(item: indexPath.item % pictures.count, section: 0), picture: pictures[indexPath.item % pictures.count]) ?? UICollectionViewCell()        } else {            // 默认Cell            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: ICycleViewConst.cellIdentifier, for: indexPath) as! ICycleViewCell            cell.configureCell(picture: pictures[indexPath.item % pictures.count], placeholderImage: placeholderImage, imgViewWidth: imgViewWidth)            return cell        }    }        public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {        delegate?.iCycleView?(cycleView: self, didSelectItemAt: indexPath.item % pictures.count)    }    }
循环轮播实现
// MARK: - 循环轮播实现extension ICycleView {        // 定时器方法,更新Cell位置    @objc private func updateCollectionViewAutoScrolling() {        if let indexPath = collectionView.indexPathsForVisibleItems.last {            let nextPath = IndexPath(item: indexPath.item + 1, section: indexPath.section)            collectionView.scrollToItem(at: nextPath, at: .centeredHorizontally, animated: true)        }    }        // 开始拖拽时,停止定时器    public func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {        timer.fireDate = Date.distantFuture    }        // 结束拖拽时,恢复定时器    public func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {        timer.fireDate = Date(timeIntervalSinceNow: autoScrollDelay)    }        /**     - 监听手动减速完成(停止滚动)     - 1.collectionView的cell显示两倍数量的图片,展示图片分为两组,默认显示第二组的第一张     - 2.左滑collectionView到第二组最后一张,即最后一个cell时,设置scrollView的contentOffset显示第一组的最后一张,继续左滑,实现了无限左滑     - 3.右滑collectionView到第一组第一张,即第一cell时,设置scrollView的contentOffset显示第二组的第一张,继续右滑,实现了无限右滑     - 4.由2,3实现无限循环     */    public func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {        let offsetX = scrollView.contentOffset.x        let page = Int(offsetX / bounds.size.width)        let itemsCount = collectionView.numberOfItems(inSection: 0)        if page == 0 {            // 第一页            collectionView.contentOffset = CGPoint(x: offsetX + CGFloat(pictures.count) * bounds.size.width, y: 0)        } else if page == itemsCount - 1 {            // 最后一页            collectionView.contentOffset = CGPoint(x: offsetX - CGFloat(pictures.count) * bounds.size.width, y: 0)        }    }        // - 滚动动画结束的时候调用    public func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {        scrollViewDidEndDecelerating(collectionView)    }        /**     - 正在滚动     - 设置分页,算出滚动位置,更新指示器     */    public func scrollViewDidScroll(_ scrollView: UIScrollView) {        let offsetX = scrollView.contentOffset.x        var page = Int(offsetX / bounds.size.width+0.5)        page = page % pictures.count        if pageControl.currentPage != page {            pageControl.currentPage = page            delegate?.iCycleView?(cycleView: self, autoScrollingItemAt: page)        }    }    }

Contact

QQ: 2256472253

Email: ixialuo@126.com

Github

转载地址:http://eqmjl.baihongyu.com/

你可能感兴趣的文章
随机取表中的数据
查看>>
SpringCloud之Netflix服务发现(Eureka)
查看>>
spring 整合redis 简单使用
查看>>
xss ***
查看>>
cygwin(hadoop)卸载过程
查看>>
spring自动代理例子
查看>>
python ftp的上传和下载
查看>>
mysql(innodb)故障
查看>>
sed命令
查看>>
【date】显示系统当前时间
查看>>
p99延迟是什么
查看>>
Swift:一般继承父类的写法
查看>>
ssh使用公钥登录客户端设置
查看>>
月薪3万的程序员告诉你:这样工作才能拿高薪(转 IT之家)
查看>>
MySQL 文本文件的导入导出数据的方法
查看>>
2012来临 iPhone5摄像头深度解析
查看>>
memcached搭建缓存系统
查看>>
↑基于httpd反向代理tomcat集群商城的部署↑
查看>>
nginx日志切割
查看>>
OSPF 原理
查看>>