| | |
| | | // |
| | | // 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") |
| | | } |
| | | } |