使用CollectionView实现无限轮播图(自动和手动轮播)

使用UICollectionView封装了一个无限循环的轮播图,实现手动轮播和定时器自动轮播,传入图片数组和标题数组,即可实现图片文字的轮播图,并有点击事件,实现代理方法可实现点击事件的处理

///调用

class HomeViewController: BaseViewController {
override func viewDidLoad() {
        super.viewDidLoad()
    let imageA = [
            "http://ygjkclass.com/pdres/ext_images/banner1.png",
            "http://ygjkclass.com/pdres/ext_images/banner3.png",
            "http://ygjkclass.com/pdres/ext_images/banner2.png",
            "http://ygjkclass.com/pdres/ext_images/tnb-2.png",
            "http://ygjkclass.com/pdres/ext_images/shimian-1.jpg"]

        let titleArray = ["第一张图片","第二张图片","第三张图片","第四张图片","第五张图片"]


        let scroller = CQScrollerPageView(frame: CGRect(x:0,y:0,width:ScreenW,height:150), images: imageA as NSArray,titles:titleArray)
        scroller.delegate = self
       view.addSubview:(scroller)

}
}
extension HomeViewController:UITableViewDataSource,CQScrollerPageViewDelegate{
   func ScrollerPageDidSelectedAtIndex(Index: Int) {

    }    
}

///源代码


import UIKit

protocol CQScrollerPageViewDelegate {

   /// 传出当前点击的Index
   ///
   /// - Parameter Index: Int
   func ScrollerPageDidSelectedAtIndex(Index:Int)
}

class CQScrollerPageView: UIView {
    var itemsArray:NSMutableArray? //图片数组
    var pageControl:UIPageControl!
    var timer:Timer? //自动滚动的定时器
    var titleArray:Array<Any>! //标题数组
    var delegate:CQScrollerPageViewDelegate? //点击的ddelegate

    init(frame:CGRect,images:NSArray,titles:Array<Any>){
        super.init(frame: frame)
        self.backgroundColor = .white
        self.frame = frame

        titleArray = titles
        itemsArray = NSMutableArray.init(array: images)

        //将图片第一张和最后一张添加到数组中的首末位置
        itemsArray?.add(images.firstObject as Any)
        itemsArray?.insert(images.lastObject as Any, at: 0)

        self.addSubview(CollectionView)
        CollectionView.contentOffset = CGPoint(x:CollectionView.bounds.size.width, y:0);
        DreawViews()
        pageControl.numberOfPages = images.count;

        timer = Timer.scheduledTimer(timeInterval: 2, target: self, selector: #selector(Cycle), userInfo: nil, repeats: true)
        RunLoop.current.add(timer!, forMode: RunLoopMode.commonModes)
    }

   @objc func Cycle() {
    if CollectionView.isDragging {
        return
    }

    let targetX = CollectionView.contentOffset.x + CollectionView.bounds.size.width
    CollectionView.setContentOffset(CGPoint(x: targetX, y: 0), animated: true)

    }

    /// 懒加载Collection
    private lazy var CollectionView:UICollectionView = {
        let layout = UICollectionViewFlowLayout()
        layout.itemSize = CGSize(width: self.bounds.size.width, height: self.bounds.size.height)
        layout.minimumLineSpacing = 0;
        layout.scrollDirection = UICollectionViewScrollDirection.horizontal;
        let collec = UICollectionView(frame: self.bounds, collectionViewLayout: layout)
        collec.backgroundColor = .white
        collec.showsHorizontalScrollIndicator = false
        collec.isPagingEnabled = true
        collec.register(UINib.init(nibName: "ScrollerCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: "PageScroller")
        collec.delegate = self
        collec.dataSource = self
        return collec
    }()


    func DreawViews() {
        pageControl = UIPageControl(frame: CGRect(x: self.centerX, y: 0, width: 0, height: 0))
        pageControl.pageIndicatorTintColor = .lightGray
        pageControl.currentPageIndicatorTintColor = .black
        pageControl.numberOfPages = (itemsArray?.count)!
        self.addSubview(pageControl!)
        pageControl.snp.makeConstraints { (make) in
            make.bottom.equalTo(0)
            make.height.equalTo(15)
            make.centerX.equalTo(self.centerX)
        }
    }

    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
        cycleScroll()
        timer?.fireDate = NSDate(timeIntervalSinceNow: 3) as Date
    }


    func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {
        cycleScroll()
    }


    //滚动的事件处理
    func cycleScroll(){
        let page = CollectionView.contentOffset.x/CollectionView.bounds.size.width;
        if (page == 0) {//滚动到左边
            CollectionView.contentOffset = CGPoint(x:CollectionView.bounds.size.width * CGFloat(((itemsArray?.count)! - 2)),y:0);
            pageControl.currentPage = (itemsArray?.count)! - 2;
        }else if (page == CGFloat((itemsArray?.count)! - 1)){//滚动到右边
            CollectionView.contentOffset = CGPoint(x:CollectionView.bounds.size.width,y:0);
            pageControl.currentPage = 0;
        }else{
            pageControl.currentPage = Int(page) - 1;
        }
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    deinit {
        guard let timer1 = self.timer
            else{ return }
        timer1.invalidate()
    }

}

extension CQScrollerPageView:UICollectionViewDelegate,UICollectionViewDataSource{

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return (itemsArray?.count)!
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let collec:ScrollerCollectionViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: "PageScroller", for: indexPath) as! ScrollerCollectionViewCell
        let url = URL(string:itemsArray![indexPath.row] as! String)
        collec.Image.kf.setImage(with: url)

        if indexPath.row >= 1 && indexPath.row <= ((itemsArray?.count)!-2){
            if (titleArray.count) > 0{
             collec.Title.text = (titleArray?[indexPath.row - 1] as! String)
            }
        }

        return collec
    }


    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        timer?.fireDate = NSDate(timeIntervalSinceNow: 3) as Date
        delegate?.ScrollerPageDidSelectedAtIndex(Index: indexPath.row - 1)
    }
}

可以使用 `UICollectionView` 或 `UIPageViewController` 来实现 iOS 图片轮播使用 `UICollectionView` 实现的方法如下: 1. 在您的视图控制器,创建一个 `UICollectionView` 实例,并将其作为子视图添加到您的视图控制器的视图。 2. 使用自定义布局实现循环滚动。可以参考以下代码: ``` class LoopCollectionViewFlowLayout: UICollectionViewFlowLayout { override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint { guard let collectionView = collectionView else { return super.targetContentOffset(forProposedContentOffset: proposedContentOffset, withScrollingVelocity: velocity) } let collectionViewSize = collectionView.bounds.size let proposedContentOffsetCenterX = proposedContentOffset.x + collectionViewSize.width * 0.5 let proposedRect = CGRect(x: proposedContentOffset.x, y: 0, width: collectionViewSize.width, height: collectionViewSize.height) guard let layoutAttributes = layoutAttributesForElements(in: proposedRect) else { return super.targetContentOffset(forProposedContentOffset: proposedContentOffset, withScrollingVelocity: velocity) } let centerX = proposedContentOffsetCenterX let offset = CGPoint(x: proposedContentOffset.x + nearestTargetOffset(for: layoutAttributes, with: centerX), y: proposedContentOffset.y) return offset } private func nearestTargetOffset(for layoutAttributes: [UICollectionViewLayoutAttributes], with centerX: CGFloat) -> CGFloat { let targetAttributes = layoutAttributes.sorted { abs($0.center.x - centerX) < abs($1.center.x - centerX) } let nearestAttribute = targetAttributes.first return nearestAttribute?.center.x ?? 0 - centerX } } ``` 3. 创建自定义 `UICollectionViewCell` 类,并在其添加一个 `UIImageView` 用于显示图片。 4. 实现 `UICollectionViewDataSource` 协议的方法,用于设置图片数据源和自定义的 `UICollectionViewCell`。 5. 实现定时器
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值