Swift collectionView 无限轮播

一:封装成CycleView


import UIKit
//无线轮播代理
protocol CycleViewDelegate:class {
    func CycleViewItemClick(_ collectionView:UICollectionView,selectedItem item:Int)
}
//无限轮播的封装
class CycleView: UIView,UICollectionViewDelegate,UICollectionViewDataSource {
    
    var collectionView:UICollectionView!
    var width:CGFloat!
    var height:CGFloat!
    var imageNames:[String]!
    var timer:Timer?
    var startContentOffsetX:CGFloat = 0
    var item:Int = 0
    var pageControl : UIPageControl?
    weak var delegate:CycleViewDelegate?
    var timeInterval:Double?
    /// frame:collectionView 的frame
    /// iamgeNames:图片名
    /// timeInterval:自动滚动的时间间隔
    /// pageControl:默认设置居中
    
    init(frame: CGRect,imageNames:[String],timeInterval:Double=2,pageControl:UIPageControl?=nil) {
        super.init(frame: frame)
        self.imageNames = imageNames
        self.pageControl = pageControl
        self.timeInterval = timeInterval
        self.width = frame.width
        self.height = frame.height
        setupCollectionView()
        setupTimer()
    }
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    //设置定时器
    func setupTimer() {
        timer = Timer.scheduledTimer(timeInterval: timeInterval!, target: self, selector: #selector(nextPage), userInfo: nil, repeats: true)
        RunLoop.main.add(timer!, forMode: .commonModes)
    }
    //自动播放下一页
    @objc func nextPage(){
        //获取当前indexpath
        let currentIndexPath = collectionView.indexPathsForVisibleItems.last
        //滚动到中间的section
        let middleIndexPath = IndexPath(item: (currentIndexPath?.item)!, section: 1)
        //滚动到中间section
        collectionView.scrollToItem(at: middleIndexPath, at: .left, animated: false)
        //滚动到目标页面
        var nextItem = middleIndexPath.item + 1
        var nextSection = middleIndexPath.section
        if nextItem == imageNames.count {
            nextItem = 0
            nextSection += 1
        }
        collectionView.scrollToItem(at: IndexPath(item: nextItem, section: nextSection), at: .left, animated: true)
    }
    //设置collectionView
    func  setupCollectionView(){
        let flowLayout = UICollectionViewFlowLayout()
        flowLayout.scrollDirection = .horizontal
        flowLayout.minimumLineSpacing = 0
        flowLayout.minimumInteritemSpacing = 0
        flowLayout.itemSize = self.bounds.size
        collectionView = UICollectionView(frame: self.bounds, collectionViewLayout: flowLayout)
        collectionView.isPagingEnabled = true
        collectionView.dataSource = self
        collectionView.delegate  = self
        collectionView.contentSize = CGSize(width: width*CGFloat(imageNames.count), height: height)
        collectionView.showsVerticalScrollIndicator = false
        collectionView.showsHorizontalScrollIndicator = false
        collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "identify")
        self.addSubview(collectionView)
        //设置pageControl
        if pageControl == nil{
            setupPageControl()
        }else{
            addSubview(pageControl!)
        }
        collectionView.scrollToItem(at: IndexPath(item: 0, section: 1), at: .left, animated: false)
    }
    //设置pageControl
    func setupPageControl(){
        let rect = CGRect(x: Int(width/2-50), y: Int(height-30), width: 100, height: 20)
        pageControl = UIPageControl(frame: rect)
        pageControl?.numberOfPages = imageNames.count
        pageControl?.currentPageIndicatorTintColor = UIColor.red
        pageControl?.isUserInteractionEnabled = false
        addSubview(pageControl!)
    }
    //重置定时器
    func resetTimer() {
        timer?.invalidate()
        timer = nil
        
    }
    // 默认三个section
    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 3
    }
    //每个section的个数
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return imageNames.count
    }
    //返回cell
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "identify", for: indexPath)
        for view:UIView in cell.contentView.subviews{
            view.removeFromSuperview()
        }
        let imageView = UIImageView(frame: cell.contentView.bounds)
        imageView.image = UIImage(named: imageNames[indexPath.row])
        cell.contentView.addSubview(imageView)
        return cell
    }
    //选中item处理
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        delegate?.CycleViewItemClick(collectionView, selectedItem: indexPath.item)
    }
    //完成滚动时,设置pageControl
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        let page = Int((scrollView.contentOffset.x+width*0.5)/width)
        let currentPage = page%imageNames.count
        pageControl?.currentPage = currentPage
    }
    //开始拖动,移除定时器
    func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
        resetTimer()
    }
    //完成拖动,重新添加定时器
    func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
        self.setupTimer()
    }
    //手动滑动处理
    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
        collectionView.scrollToItem(at: IndexPath(item: (pageControl?.currentPage)!, section: 1), at: .left, animated: false)
    }
}

二:调用

import UIKit
//遵守代理
class ViewController: UIViewController,CycleViewDelegate {
    //实现代理方法
    func CycleViewItemClick(_ collectionView: UICollectionView, selectedItem item: Int) {
        print(item)
    }
    override func viewDidLoad() {
        super.viewDidLoad()
        //图片名
        let imageArr = ["FirstPicture","SecondPicture","ThirdPicture"]
        //滚动视图的frame
        let rect = CGRect(x: 0, y: 20, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.width*9/16)
        
        //1.默认pageControl居中,默认timeInterval为2s,
        let cycleView =  CycleView(frame: rect, imageNames: imageArr,timeInterval:3)
        //实现代理
        cycleView.delegate = self
        //添加到View
        self.view.addSubview(cycleView)
        
        //       2.自定义pageControl的位置和属性
        //        let pageControl = UIPageControl(frame: CGRect(x: 100, y: 100, width: 100, height: 40))
        //        pageControl.currentPageIndicatorTintColor = UIColor.blue
        //        pageControl.isUserInteractionEnabled = false
        //        pageControl.numberOfPages = imageArr.count
        //        let cycleView = CycleView(frame: rect, imageNames: imageArr, pageControl: pageControl)
        //        cycleView.delegate = self
        //        self.view.addSubview(cycleView)
    }
}

三:效果

猜你喜欢

转载自www.cnblogs.com/chenxiaopao/p/9210776.html