• iOS swift版本无限滚动轮播图


    之前写过oc版本的无限滚动轮播图,现在来一个swift版本全部使用snapKit布局,数字还是pageConrrol样式可选

    enum typeStyle: Int {
        case pageControl
        case label
    }
    
    

    效果图:

    代码:

    //
    //  TYCarouselView.swift
    //  hxquan-swift
    //
    //  Created by Tiny on 2018/11/12.
    //  Copyright © 2018年 hxq. All rights reserved.
    //  轮播图
    
    import UIKit
    
    let ImgPlaceHolder = UIImage(named: "picture")
    
    enum typeStyle: Int {
        case pageControl
        case label
    }
    
    class TYCarouselCell: UICollectionViewCell {
        
        var url: String = ""{
            didSet{
                let cacheImg = SDImageCache.shared().imageFromDiskCache(forKey: url)
                imgView.contentMode = .center
                imgView.sd_setImage(with: URL(string: url),placeholderImage:cacheImg ?? ImgPlaceHolder) { [unowned self] (image, error, _, _) in
                    if image != nil && error == nil{
                        self.imgView.contentMode = .scaleAspectFill
                    }
                }
            }
        }
        
        lazy var imgView: UIImageView = {
            let imgView = UIImageView()
            imgView.layer.masksToBounds = true
            imgView.contentMode = .center
            imgView.image = ImgPlaceHolder
            return imgView
        }()
        
        override init(frame: CGRect) {
            super.init(frame: frame)
            setupUI()
        }
        
        required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
            setupUI()
        }
        
        func setupUI(){
            contentView.addSubview(imgView)
            
            imgView.snp.makeConstraints { (make) in
                make.edges.equalToSuperview()
            }
        }
    }
    
    class TYCarouselView: UIView {
        
        var style: typeStyle = .pageControl{
            didSet{
                if style == .pageControl{
                    if pageControl.superview == nil{
                        addSubview(pageControl)
                        pageControl.snp.makeConstraints { (make) in
                            make.centerX.equalToSuperview()
                            make.bottom.equalToSuperview().offset(-10)
                        }
                    }
                    if label.superview != nil{
                        label.removeFromSuperview()
                    }
                }else{
                    if label.superview == nil{
                        addSubview(label)
                        label.snp.makeConstraints { (make) in
                            make.right.equalToSuperview().offset(-20)
                            make.bottom.equalToSuperview().offset(-20)
                        }
                    }
                    if pageControl.superview != nil{
                        pageControl.removeFromSuperview()
                    }
                }
            }
        }
        
        /// 定时器是否开启
        var isTimerEnable = true
        
        fileprivate let maxsection: Int = 100
        
        /// 滚动间隔
        public let scroInterval: TimeInterval = 4
        
        private var selectonBlock: ((Int)->Void)?
        
        public var images = [String]() {
            didSet{
                //重写images set方法
                //更新数据源
                collectionView.reloadData()
                if style == .pageControl {
                    pageControl.numberOfPages = images.count
                }else{
                    if oldValue.count == 0{
                        label.attributedText = labelAttrText(1)
                    }
                    label.isHidden = images.count == 0
                }
                if isTimerEnable && !images.isEmpty{
                    timerStart()
                }
            }
        }
        
        lazy var pageControl: UIPageControl = {
            let pageControl = UIPageControl()
            pageControl.sizeToFit()
            return pageControl
        }()
        
        lazy var label: UILabel = {
            let label = UILabel()
            label.font = UIFont.systemFont(ofSize: 12)
            label.textColor = UIColor.white
            label.attributedText = labelAttrText(0)
            label.isHidden = true
            return label
        }()
        
        fileprivate lazy var collectionView: UICollectionView = { [unowned self] in
            let layout = UICollectionViewFlowLayout()
            layout.scrollDirection = .horizontal
            layout.minimumLineSpacing = 0
            layout.minimumInteritemSpacing = 0
            layout.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
            let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
            collectionView.backgroundColor = UIColor.white
            collectionView.showsVerticalScrollIndicator = false
            collectionView.showsHorizontalScrollIndicator = false
            collectionView.delegate = self
            collectionView.dataSource = self
            collectionView.isPagingEnabled = true
            collectionView.register(TYCarouselCell.self, forCellWithReuseIdentifier: "TYCarouselCell")
            
            return collectionView
            }()
        
        fileprivate lazy var timer: Timer = { [unowned self] in
            let timer = Timer(timeInterval: scroInterval, target: self, selector: #selector(timerInterval), userInfo: nil, repeats: true)
            RunLoop.current.add(timer, forMode: .common)
            return timer
        }()
        
        
        override init(frame: CGRect) {
            super.init(frame: frame)
            setupUI()
        }
        
        convenience init(frame: CGRect,selectonBlock: ((Int)->Void)?){
            self.init(frame: frame)
            self.selectonBlock = selectonBlock
        }
        
        required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
        }
        
        private func setupUI(){
            addSubview(collectionView)
            collectionView.snp.makeConstraints { (make) in
                make.edges.equalToSuperview()
            }
            
            addSubview(pageControl)
            pageControl.snp.makeConstraints { (make) in
                make.bottom.equalToSuperview().offset(-10)
                make.centerX.equalToSuperview()
            }
        }
        
        @objc func timerInterval(){
            //取当前idnexPath
            if let currentIndexPath = collectionView.indexPathsForVisibleItems.last{
                //先让collectionViev滚动到中间
                let currentIndexPathReset = IndexPath(row: currentIndexPath.row, section: maxsection/2)
                collectionView.scrollToItem(at: currentIndexPathReset, at: .left, animated: false)
                
                //让当前indexPath.row++
                var row = currentIndexPath.row + 1
                var nextsection = currentIndexPathReset.section
                if row >= images.count{
                    row = 0
                    nextsection = nextsection + 1
                }
                if style == .pageControl {
                    pageControl.currentPage = row
                }else{
                    label.attributedText = labelAttrText(row+1)
                }
                let nextIndexPath = IndexPath(row: row, section:nextsection)
                collectionView.scrollToItem(at: nextIndexPath, at: .left, animated: true)
            }
        }
        
        private func timerStart(){
            if !timer.isValid {
                timer.fire()
            }
        }
        
        private func timerPause(){
            if timer.isValid {
                timer.invalidate()
            }
        }
        
        private func labelAttrText(_ index: Int) -> NSAttributedString{
            let lf = "(index)"
            let rt = "(images.count)"
            let str = lf + "/" + rt
            let attr = NSMutableAttributedString(string: str)
            attr.setAttributes([NSAttributedString.Key.foregroundColor : UIColor.red], range: NSRange(location: 0, length: 1))
            return attr
        }
    }
    
    extension TYCarouselView: UICollectionViewDataSource,UICollectionViewDelegate,UICollectionViewDelegateFlowLayout{
        
        func numberOfSections(in collectionView: UICollectionView) -> Int {
            return maxsection
        }
        
        func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
            return images.count
        }
        
        func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "TYCarouselCell", for: indexPath) as! TYCarouselCell
            cell.url = images[indexPath.row]
            return cell
        }
        
        func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
            return CGSize( self.bounds.size.width, height: self.bounds.size.height)
        }
        
        func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
            selectonBlock?(indexPath.row)
        }
        
        //结束滚动
        func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
            let index = Int(scrollView.contentOffset.x / self.bounds.size.width + 0.5) % images.count
            if style == .pageControl {
                pageControl.currentPage = index
            }else{
                label.attributedText = labelAttrText(index+1)
            }
            if(isTimerEnable){
                //定时器启动
                if timer.isValid {
                    timer.fireDate = Date.init(timeIntervalSinceNow: scroInterval)
                }
            }
        }
        
        //拖动
        func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
            if isTimerEnable{
                //定时器暂停
                if timer.isValid {
                    timer.fireDate = Date.distantFuture
                }
            }
        }
    }
    
    

    使用方法:

        lazy var carouselView: TYCarouselView = { [unowned self] in
            let carouselView = TYCarouselView(frame: .zero, selectonBlock: { (index) in
                print("(index)")
            })
            carouselView.style = .label
            carouselView.layer.masksToBounds = true
            carouselView.layer.cornerRadius = 10
            return carouselView
        }()
    
        override func viewDidLoad() {
            super.viewDidLoad()
                //添加到父视图
            view.addSubview(carouselView)
            //设置约束
            carouselView.snp.makeConstraints { (make) in
                make.left.equalTo(15)
                make.right.equalTo(-15)
                make.top.equalTo(10)
                make.height.equalTo(170)
            }
            //设置数据源
            var imgs = [String]()
            for _ in 0..<5{
                imgs.append("图url")
            }
            self.carouselView.images = imgs
        }
    
  • 相关阅读:
    你人生中的那口井挖了没有?
    Stream接口
    console (控制台)
    assert.fail()
    assert.strictEqual()
    assert.equal()
    assert.ifError()
    assert.ok()
    nodejs assert 模块
    闭包
  • 原文地址:https://www.cnblogs.com/qqcc1388/p/10000607.html
Copyright © 2020-2023  润新知