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~