swift UICollectionView 实现无限轮播图

2016-09-08  本文已影响0人  Sparkle_S

无线轮播图的实现方式有很多,这里介绍如何通过 UICollectionView 实现无线轮播图.效果图如下:


无限轮播图

具体实现过程见代码

enum PageCtrlPosition {
  case Left
  case Center
  case Right
}
class BannerView: UIView ,UICollectionViewDelegate,UICollectionViewDataSource{
  
  var clickBannerBlock:((num:Int) -> () )?   //点击轮播图,回调点击的序列号
  var isHasBannerBlock:((isHas:Bool) -> ())?   //请求 banner 完成,回调是否有 banner
  var pageCtrlPosition:PageCtrlPosition = .Center
  var pageCtrlSelectedColor :UIColor = UIColor.whiteColor() //分页控制器选中时的颜色,默认白色
  //
  var bannerArray:[String] = []    //轮播图数组
  var urlStr :String?  //轮播图 url 用于标注缓存
  var collecView:UICollectionView!
  var timer:NSTimer?
  var pageCtrl:UIPageControl!
  
  // MARK: - system method
  override func awakeFromNib() {
    super.awakeFromNib()
    self.setUp()
  }
  override init(frame: CGRect) {
    super.init(frame: frame)
    self.setUp()
  }
  required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
  }
  func setUp() {
    self.layer.masksToBounds = true
    //创建 collectionView
    collecView = self.createCollectionView(0, itemSize: CGSizeMake(SCREEN_WIDTH, self.frame.size.height), sectionInset: UIEdgeInsetsMake(0, 0, 0, 0), direction: .Horizontal)
    collecView.delegate = self
    collecView.dataSource = self
    collecView.pagingEnabled = true
    self.addSubview(collecView)
    //注册 cell
    collecView.registerClass(UICollectionViewCell.self, forCellWithReuseIdentifier: "CollectionCell")
    //创建 pageCtrl
    pageCtrl = UIPageControl()
    pageCtrl.pageIndicatorTintColor = UIColor.init(white: 0.4, alpha: 0.6)
    self.addSubview(pageCtrl)
  }
  // MARK: public method
  /**
   方法1:请求轮播图数据,然后创建,点击进入不同界面
 
   - parameter url: 请求轮播图的url
   */
  func requestBannerData(url:String) {
    urlStr = url
    //添加请求数据逻辑
  }
  /**
   方法2:已知轮播图数据,然后创建,点击回调
   
   - parameter array: 轮播图的图片链接数组
   */
  func createBannerView(array:[String]) {
    if array.count == 0 {
      if let isHasBannerBlock = isHasBannerBlock {
        isHasBannerBlock(isHas: false)
      }
      return
    }
    bannerArray = [array[0]] + array + [array[array.count - 1]]
    collecView.reloadData()
    //设置 collectionView 的 contentsize
    collecView.scrollToItemAtIndexPath(NSIndexPath.init(forRow: 1, inSection: 0), atScrollPosition: .Left, animated: false)
    //设置 pageCtrl
    pageCtrl.currentPageIndicatorTintColor = pageCtrlSelectedColor
    pageCtrl.numberOfPages = bannerArray.count - 2
    let pageCtrlWidth = CGFloat(bannerArray.count) * 20
    let pointY = self.frame.height-25
    switch pageCtrlPosition {
    case .Left:
      pageCtrl.frame = CGRectMake(0, pointY, pageCtrlWidth , 25)
    case .Center:
      pageCtrl.frame = CGRectMake((SCREEN_WIDTH - pageCtrlWidth)/2.0, pointY, pageCtrlWidth, 25)
    case .Right:
      pageCtrl.frame = CGRectMake(SCREEN_WIDTH-pageCtrlWidth, pointY, pageCtrlWidth, 25)
    }
    //当只有一张图片时,关闭轮播功能
    if bannerArray.count <= 3 {
      collecView.scrollEnabled = false
      pageCtrl.hidden = true
      timer?.invalidate()
    }else{
      collecView.scrollEnabled = true
      pageCtrl.hidden = false
      self.addTimer()
    }
  }
  // MARK: - private method
  func addTimer() {
    if timer == nil {
      timer = NSTimer.scheduledTimerWithTimeInterval(3.0, target: self, selector: #selector(BannerView.nextBanner), userInfo: nil, repeats: true)
      NSRunLoop.currentRunLoop().addTimer(timer!, forMode: NSRunLoopCommonModes)
    }
  }
  func nextBanner() {
    var index = Int(collecView.contentOffset.x/SCREEN_WIDTH)
    if index == bannerArray.count-2{
      index = 1
      collecView.scrollToItemAtIndexPath(NSIndexPath.init(forRow: 0, inSection: 0), atScrollPosition: .Left, animated: false)
    }else{
      index += 1
    }
    UIView.animateWithDuration(0.5) {
      self.collecView.scrollToItemAtIndexPath(NSIndexPath.init(forRow: index, inSection: 0), atScrollPosition: .Left, animated: true)
    }
  }
  // MARK: - UIScrollViewDelegate
  func scrollViewDidScroll(scrollView: UIScrollView) {
    //滚动时修改 pagecontrol 的当前页数
    let index = Int(collecView.contentOffset.x/SCREEN_WIDTH)
    if index == 0 && index == (bannerArray.count-1) {
      pageCtrl.hidden = true
    }else{
      pageCtrl.hidden = false
      pageCtrl.currentPage = index - 1
    }
  }
  func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
    //图片停止减速时,更改目标页
    var index = Int(collecView.contentOffset.x/SCREEN_WIDTH)
    if index == bannerArray.count - 1 {
      index = 1
      collecView.scrollToItemAtIndexPath(NSIndexPath.init(forRow: index, inSection: 0), atScrollPosition: .Left, animated: false)
    }else if index == 0{
      index = bannerArray.count-1
      collecView.scrollToItemAtIndexPath(NSIndexPath.init(forRow: index, inSection: 0), atScrollPosition: .Left, animated: false)
    }else{
      index += 1
    }
  }
  func scrollViewWillBeginDragging(scrollView: UIScrollView) {
    //开始拖拽时关闭定时器
    timer?.invalidate()
    timer = nil
  }
  func scrollViewDidEndDragging(scrollView: UIScrollView, willDecelerate decelerate: Bool) {
    //结束拖拽时开启定时器
    self.addTimer()
  }
  // MARK: - UICollectionViewDelegate
  func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return bannerArray.count
  }
  func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCellWithReuseIdentifier("CollectionCell", forIndexPath: indexPath)
    for subView in cell.subviews {
      subView.removeFromSuperview()
    }
    let imageV = UIImageView.init(frame: CGRectMake(0, 0, SCREEN_WIDTH, cell.frame.size.height))
    imageV.image = UIImage.init(named: "tips")
    cell.addSubview(imageV)
    return cell
  }
  func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
    if let clickBannerBlock = clickBannerBlock {
      clickBannerBlock(num: indexPath.row)
    }else{
      PushToViewCtrl(UIViewController.init())
    }
  }
}

调用也是极其简单的

    let bannerView = BannerView.init(frame: CGRectMake(0, 64, SCREEN_WIDTH, 150))
    bannerView.clickBannerBlock = { (num:Int) in
      print(num)
    }
    bannerView.isHasBannerBlock = { (isHas:Bool) in
      //修改高度
      bannerView.frame = CGRectZero
    }
    self.view.addSubview(bannerView)
    bannerView.createBannerView(["","",""])

期待你的评论建议O(∩_∩)O~

上一篇下一篇

猜你喜欢

热点阅读