无故事王国
2024-03-12 fd05d3dfc61ad3482cfd577279cff72f74c68cf6
WanPai/Common/View/CommonBannerView.swift
@@ -1,208 +1,208 @@
    //
    //  CommonBannerView.swift
    //  WanPai
    //
    //  Created by 无故事王国 on 2023/6/30.
    //
//
//  CommonBannerView.swift
//  WanPai
//
//  Created by 无故事王国 on 2023/6/30.
//
import UIKit
import SDWebImage
struct CommonBannerModel {
   var index = 0 //自定义索引
   var id:Int? //ID
   var name:String? //名称
   var resource:String? //数据源:URL等
   var mediaType:CommonBannerView.MediaType?
            var index = 0 //自定义索引
            var id:Int? //ID
            var name:String? //名称
            var resource:String? //数据源:URL等
            var mediaType:CommonBannerView.MediaType?
}
class CommonBannerView: UIView, UICollectionViewDelegate, UICollectionViewDataSource,UICollectionViewDelegateFlowLayout {
   enum MediaType {
      case videoUrl,imageUrl,imageLocal,videoLocal
   }
   private lazy var collectionView:UICollectionView = {
      var layout = UICollectionViewFlowLayout()
      layout.minimumLineSpacing = 0
      layout.minimumInteritemSpacing = 0
      layout.scrollDirection = .horizontal
      layout.sectionInset = .zero
      layout.headerReferenceSize = .zero
      layout.footerReferenceSize = .zero
      layout.itemSize = CGSize(width: self.width, height: self.height)
      let collectionView = UICollectionView(frame:CGRect(x: 0, y: 0, width: self.width, height: self.height), collectionViewLayout: layout)
      collectionView.delegate = self
      collectionView.dataSource = self
      collectionView.isPagingEnabled = true
      collectionView.showsHorizontalScrollIndicator = false
      collectionView.register(CommonBannerViewCell.self, forCellWithReuseIdentifier: "BannerView")
      collectionView.decelerationRate = .normal
      collectionView.contentInsetAdjustmentBehavior = .never
      collectionView.backgroundColor = .white
      collectionView.bounces = false
      return collectionView
   }()
   private lazy var pageControl:UIPageControl = {
      let control = UIPageControl()
      control.currentPageIndicatorTintColor = .white
      control.pageIndicatorTintColor = .gray.withAlphaComponent(0.6)
      return control
   }()
   private var timer:Timer?
   private var items = [CommonBannerModel]()
   private var selectClouse:((CommonBannerModel)->Void)?
   private var autoRoll:Bool = true
   private var currentPage:Int = 0
   private var timeInterval:Int = 5
   override func awakeFromNib() {
      super.awakeFromNib()
      setUI()
   }
   public func setItems(items:[CommonBannerModel],autoRoll:Bool = true,selectClouse:((CommonBannerModel)->Void)? = nil){
      self.items = items
      if items.count > 1{
         self.items.append(items.first!)
      }
      self.autoRoll = autoRoll
      self.selectClouse = selectClouse
      if items.count <= 1{self.autoRoll = false}
      setUI()
      collectionView.reloadData()
      if self.autoRoll{
         DispatchQueue.main.asyncAfter(deadline: .now()+5) {
            self.startTimer()
         }
      }
   }
   private func setUI(){
      addSubview(collectionView)
      collectionView.snp.makeConstraints { make in
         make.edges.equalToSuperview()
      }
      if items.count > 1{
         pageControl.numberOfPages = items.count - 1
         addSubview(pageControl)
         pageControl.snp.makeConstraints { make in
            make.centerX.equalToSuperview()
            make.bottom.equalToSuperview().offset(-10)
            make.height.equalTo(8)
         }
      }
   }
   private func startTimer(){
      timer = Timer(timeInterval: TimeInterval(timeInterval), repeats: true, block: {[weak self] t in
         guard let weakSelf = self else { return }
         var page = weakSelf.collectionView.contentOffset.x / weakSelf.collectionView.width
         weakSelf.currentPage = Int(page + 1)
         if weakSelf.currentPage >= weakSelf.pageControl.numberOfPages{
            weakSelf.currentPage = 0
            weakSelf.collectionView.setContentOffset(.zero, animated: false)
            weakSelf.pageControl.currentPage = 0
         }
         weakSelf.collectionView.setContentOffset(CGPoint(x: weakSelf.currentPage * Int(weakSelf.width), y: 0), animated: true)
      })
      timer?.fire()
      RunLoop.current.add(timer!, forMode: .common)
   }
   func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
      return items.count
   }
   func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
      let item = items[indexPath.row]
      selectClouse?(item)
   }
   func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
      return CGSize(width:collectionView.bounds.size.width,height:ceil(collectionView.bounds.size.height))
   }
   func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
      print("--开始滑动")
      timer?.fireDate = Date.distantFuture
   }
   func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
      let page = scrollView.contentOffset.x / scrollView.width
      if page.int >= pageControl.numberOfPages{
         pageControl.currentPage = 0
      }else{
         pageControl.currentPage = page.int
      }
      print("--结束滑动")
      timer?.fireDate = Date.init(timeIntervalSinceNow: 3.0) //3秒后开启
   }
   func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {
      let page = scrollView.contentOffset.x / scrollView.width
      if page.int >= pageControl.numberOfPages{
         pageControl.currentPage = 0
      }else{
         pageControl.currentPage = page.int
      }
   }
   func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
      let page = scrollView.contentOffset.x / scrollView.width
      if page.int >= pageControl.numberOfPages{
         pageControl.currentPage = 0
         collectionView.setContentOffset(.zero, animated: false)
      }else{
         pageControl.currentPage = page.int
      }
   }
   func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
      let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "BannerView", for: indexPath) as! CommonBannerViewCell
      let item = items[indexPath.row]
      switch item.mediaType {
         case .imageUrl:
            if let i = item.resource{
               cell.imgView.sd_setImage(with: URL(string: i))
            enum MediaType {
                        case videoUrl,imageUrl,imageLocal,videoLocal
            }
         case .imageLocal:
            if let i = item.resource{
               cell.imgView.image = UIImage(named: i)
            private lazy var collectionView:UICollectionView = {
                        var layout = UICollectionViewFlowLayout()
                        layout.minimumLineSpacing = 0
                        layout.minimumInteritemSpacing = 0
                        layout.scrollDirection = .horizontal
                        layout.sectionInset = .zero
                        layout.headerReferenceSize = .zero
                        layout.footerReferenceSize = .zero
                        layout.itemSize = CGSize(width: self.width, height: self.height)
                        let collectionView = UICollectionView(frame:CGRect(x: 0, y: 0, width: self.width, height: self.height), collectionViewLayout: layout)
                        collectionView.delegate = self
                        collectionView.dataSource = self
                        collectionView.isPagingEnabled = true
                        collectionView.showsHorizontalScrollIndicator = false
                        collectionView.register(CommonBannerViewCell.self, forCellWithReuseIdentifier: "BannerView")
                        collectionView.decelerationRate = .normal
                        collectionView.contentInsetAdjustmentBehavior = .never
                        collectionView.backgroundColor = .white
                        collectionView.bounces = false
                        return collectionView
            }()
            private lazy var pageControl:UIPageControl = {
                        let control = UIPageControl()
                        control.currentPageIndicatorTintColor = .white
                        control.pageIndicatorTintColor = .gray.withAlphaComponent(0.6)
                        return control
            }()
            private var timer:Timer?
            private var items = [CommonBannerModel]()
            private var selectClouse:((CommonBannerModel)->Void)?
            private var autoRoll:Bool = true
            private var currentPage:Int = 0
            private var timeInterval:Int = 5
            override func awakeFromNib() {
                        super.awakeFromNib()
                        setUI()
            }
         default:break
      }
      return cell
   }
            public func setItems(items:[CommonBannerModel],autoRoll:Bool = true,selectClouse:((CommonBannerModel)->Void)? = nil){
                        self.items = items
                        if items.count > 1{
                                    self.items.append(items.first!)
                        }
                        self.autoRoll = autoRoll
                        self.selectClouse = selectClouse
                        if items.count <= 1{self.autoRoll = false}
                        setUI()
                        collectionView.reloadData()
                        if self.autoRoll{
                                    DispatchQueue.main.asyncAfter(deadline: .now()+5) {
                                                self.startTimer()
                                    }
                        }
            }
            private func setUI(){
                        addSubview(collectionView)
                        collectionView.snp.makeConstraints { make in
                                    make.edges.equalToSuperview()
                        }
                        if items.count > 1{
                                    pageControl.numberOfPages = items.count - 1
                                    addSubview(pageControl)
                                    pageControl.snp.makeConstraints { make in
                                                make.centerX.equalToSuperview()
                                                make.bottom.equalToSuperview().offset(-10)
                                                make.height.equalTo(8)
                                    }
                        }
            }
            private func startTimer(){
                        timer = Timer(timeInterval: TimeInterval(timeInterval), repeats: true, block: {[weak self] t in
                                    guard let weakSelf = self else { return }
                                    var page = weakSelf.collectionView.contentOffset.x / weakSelf.collectionView.width
                                    weakSelf.currentPage = Int(page + 1)
                                    if weakSelf.currentPage >= weakSelf.pageControl.numberOfPages{
                                                weakSelf.currentPage = 0
                                                weakSelf.collectionView.setContentOffset(.zero, animated: false)
                                                weakSelf.pageControl.currentPage = 0
                                    }
                                    weakSelf.collectionView.setContentOffset(CGPoint(x: weakSelf.currentPage * Int(weakSelf.width), y: 0), animated: true)
                        })
                        timer?.fire()
                        RunLoop.current.add(timer!, forMode: .common)
            }
            func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
                        return items.count
            }
            func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
                        let item = items[indexPath.row]
                        selectClouse?(item)
            }
            func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
                        return CGSize(width:collectionView.bounds.size.width,height:ceil(collectionView.bounds.size.height))
            }
            func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
                        print("--开始滑动")
                        timer?.fireDate = Date.distantFuture
            }
            func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
                        let page = scrollView.contentOffset.x / scrollView.width
                        if page.int >= pageControl.numberOfPages{
                                    pageControl.currentPage = 0
                        }else{
                                    pageControl.currentPage = page.int
                        }
                        print("--结束滑动")
                        timer?.fireDate = Date.init(timeIntervalSinceNow: 3.0) //3秒后开启
            }
            func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {
                        let page = scrollView.contentOffset.x / scrollView.width
                        if page.int >= pageControl.numberOfPages{
                                    pageControl.currentPage = 0
                        }else{
                                    pageControl.currentPage = page.int
                        }
            }
            func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
                        let page = scrollView.contentOffset.x / scrollView.width
                        if page.int >= pageControl.numberOfPages{
                                    pageControl.currentPage = 0
                                    collectionView.setContentOffset(.zero, animated: false)
                        }else{
                                    pageControl.currentPage = page.int
                        }
            }
            func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
                        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "BannerView", for: indexPath) as! CommonBannerViewCell
                        let item = items[indexPath.row]
                        switch item.mediaType {
                                    case .imageUrl:
                                                if let i = item.resource{
                                                            cell.imgView.sd_setImage(with: URL(string: i))
                                                }
                                    case .imageLocal:
                                                if let i = item.resource{
                                                            cell.imgView.image = UIImage(named: i)
                                                }
                                    default:break
                        }
                        return cell
            }
}
class CommonBannerViewCell: UICollectionViewCell {
   lazy var imgView:UIImageView = {
      let img = UIImageView()
      img.contentMode = .scaleToFill
      return img
   }()
            lazy var imgView:UIImageView = {
                        let img = UIImageView()
                        img.contentMode = .scaleToFill
                        return img
            }()
   override init(frame: CGRect) {
      super.init(frame: frame)
      contentView.addSubview(imgView)
      imgView.snp.makeConstraints { make in
         make.edges.equalToSuperview()
      }
   }
            override init(frame: CGRect) {
                        super.init(frame: frame)
                        contentView.addSubview(imgView)
                        imgView.snp.makeConstraints { make in
                                    make.edges.equalToSuperview()
                        }
            }
   required init?(coder aDecoder: NSCoder) {
      fatalError("init(coder:) has not been implemented")
   }
            required init?(coder aDecoder: NSCoder) {
                        fatalError("init(coder:) has not been implemented")
            }
}