美文网首页
UICollectionView

UICollectionView

作者: T92 | 来源:发表于2016-09-11 15:24 被阅读178次

什么是CollectionView,看图,可以滚动的那个电影栏就是

继承关系

UICollectionView继承自UIScrollView,所以UIScrollView有的属性UICollectionView也有,如果UIScrollView不清楚,开启传送门:http://www.jianshu.com/p/5917a900d6dc
和UICollectionView很像的类UITableView,传送门:http://www.jianshu.com/p/4e870acd81e3

UICollectionView基础

import UIKit

class ViewController: UIViewController {
    //MARK: - 属性
    //继承关系:UICollectionView -> UIScrollView
    var collectionView:UICollectionView? = nil
    override func viewDidLoad() {
        super.viewDidLoad()
        //1.创建UICollectionView子类对象(layout类型的都型,一般使用UICollectionViewFlowLayout)
        //作用:专门负责CollectionView的布局
        let layout = UICollectionViewFlowLayout()
        
        //设置cell的大小(这种方式设置的每个cell的大小是相同的,想要不同,就在delegate里面设置)
        //layout.itemSize = CGSizeMake(100, 150)
        
        //=====================
        
        //设置每个cell之间的间距(行间距和列间距)
        layout.minimumLineSpacing = 0 //设置这个属性就是直接设置了每一行cell之间的间距
        layout.minimumInteritemSpacing = 0 //设置这个属性就是直接设置了列间距
        //设置滚动方向(默认上下滚动)
        //layout.scrollDirection = .Horizontal
        
        //=====================
        
        //2.创建UICollectionView对象
        //参数2:
        self.collectionView = UICollectionView(frame: self.view.bounds, collectionViewLayout: layout)
        //3.添加到界面
        self.view.addSubview(self.collectionView!)
        //4.设置背景颜色
        self.collectionView?.backgroundColor = UIColor.whiteColor()
        //5.设置代理
        self.collectionView?.dataSource = self
        self.collectionView?.delegate = self
        
        //************
        //6.注册cell
        //注册Xib创建的cell
        //self.collectionView?.registerNib(<#T##nib: UINib?##UINib?#>, forCellWithReuseIdentifier: <#T##String#>)
        //注册手写的cell或系统cell
        //参数1:cell类型
        //参数2:ID
        self.collectionView?.registerClass(UICollectionViewCell.self, forCellWithReuseIdentifier: "cell")
    }
}

extension ViewController:UICollectionViewDataSource{
    //设置每个分组的cell个数(不分组的话默认分组数为1)
    func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 100
    }
    //创建cell
    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        //1.去复用池中查找是否有可以复用的cell,如过找到就返回那个可以复用的cell,没有就 <自动创建> 一个新的cell返回(在这之前必须去注册cell)
        //参数1:ID
        //参数2:
        let cell = collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath)
        //2.刷新数据
        cell.backgroundColor = UIColor(red: CGFloat(arc4random() % 256) / 255, green: CGFloat(arc4random() % 256) / 255, blue: CGFloat(arc4random() % 256) / 255, alpha: 1)
        return cell
    }
}

//UICollectionViewDelegateFlowLayout遵守了UICollectionViewDelegate协议,UICollectionViewDelegate遵守了UIScrollViewDelegate
extension ViewController:UICollectionViewDelegateFlowLayout{
    //设置每个cell的大小
    //可以让不同分组设置不同的大小
    //indexPath -> cell的位置
    //indexPath.section -> 组
    //indexPath.item -> 个
    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
        //方案1:确定每个cell的大小,和每一行cell的个数去计算间距
        //return CGSizeMake(100, 150)
        //方案2:确定每个cell的间距,和每一行cell的个数,去计算cell的大小
        let width = self.view.bounds.width / 4
        return CGSizeMake(width, 150)
    }
    
    //设置每个分组到CollectionView上下左右的间距
    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAtIndex section: Int) -> UIEdgeInsets {
        //方案1对应设置:确定每个cell的大小,和每一行cell的个数去计算间距
        //let margin = (self.view.bounds.width - 100 * 3) / 4
        //return UIEdgeInsetsMake(margin, margin, margin, margin)
        //方案2对应设置:确定每个cell的间距,和每一行cell的个数,去计算cell的大小
        return UIEdgeInsetsMake(0, 0, 0, 0)
    }
}

UICollectionView循环滚动

有多张图片,滑动可以切换,效果图看不出来


效果图 原理图

解释:加入红黑蓝要循环滚动,那么建立一个内容很宽的CollectionView,上面循环添加很多组红黑蓝的图,再将偏移量设置到内容的中间,造成无限循环的假象。

在下面这个例子中,用手写和Xib两种方式写了循环的CollectionView的Cell,只是将手写版的注册和和创建注释掉了,采用的是Xib版的。现将Xib和手写版一起展出,便于参考

结构
  • ViewController
import UIKit

class ViewController: UIViewController {

    //MARK: - 属性
    //1.collectionView
    var collectionView:UICollectionView? = nil
    //2.数据源数组
    lazy var dataArray:[UIImage] = {
        var tempArray = [UIImage]()
        for item in 1...4{
            let image = UIImage(named: "41_\(item).jpg")//偷懒使用name方式创建
            tempArray.append(image!)
        }
        return tempArray
    }()
    override func viewDidLoad() {
        super.viewDidLoad()
        //创建layout
        let layout = UICollectionViewFlowLayout()
        //设置最小间距
        layout.minimumLineSpacing = 0
        layout.minimumInteritemSpacing = 0
        //滚动方向
        layout.scrollDirection = .Horizontal//水平方向
        //创建对象
        self.collectionView = UICollectionView(frame: CGRectMake(0, 0, self.view.bounds.width, 200), collectionViewLayout: layout)
        //添加到界面
        self.view.addSubview(collectionView!)
        //设置代理
        self.collectionView?.dataSource = self
        self.collectionView?.delegate = self
        
        //********************
        //注册手写cell或者storyBoard方式创建的cell
        //self.collectionView?.registerClass(MyCollectionViewCell.self, forCellWithReuseIdentifier: "cell")
        //Xib注册cell
        let nib = UINib(nibName: "XibCollectionViewCell", bundle: nil)
        self.collectionView?.registerNib(nib, forCellWithReuseIdentifier: "cell")
        //********************
        
        //设置分页
        self.collectionView?.pagingEnabled = true
        
        //设置偏移量
        //将偏移量设置到内容中间,可以左右滑动5000次,造成循环假象
        self.collectionView?.contentOffset = CGPointMake(10000 / 2 * self.collectionView!.bounds.width,0)
        //隐藏滑条
        self.collectionView?.showsHorizontalScrollIndicator = false
    }
}

extension ViewController:UICollectionViewDataSource{
    //设置cell个数
    func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        //设置无限多张实现循环的效果(实际上是不能循环的)
        return 10000
    }
    //创建cell
    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        //创建手写cell
        //let cell = collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath) as! MyCollectionViewCell
        //创建Xib的cell
        let cell = collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath) as! XibCollectionViewCell
        //刷新数据
        cell.imageView.image = self.dataArray[indexPath.row % 4]
        return cell
    }
}

extension ViewController:UICollectionViewDelegateFlowLayout{
    //size
    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize{
        return collectionView.frame.size
    }
    //间距
    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAtIndex section: Int) -> UIEdgeInsets{
        return UIEdgeInsetsMake(0, 0, 0, 0)
    }
}
  • MyCollectionViewCell
import UIKit
//1.创建所有的子视图对应的属性
//2.在构造方法中添加子视图
//3.计算frame

class MyCollectionViewCell: UICollectionViewCell {
    //MARK: - 属性
    let imageView = UIImageView()
    
    //MARK: - 构造方法
    override init(frame: CGRect) {
        super.init(frame: frame)
        self.contentView.addSubview(imageView)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    //MARK: - 计算frame
    override func layoutSubviews() {
        super.layoutSubviews()
        imageView.frame = self.bounds
    }
}
  • Xib
xib
  • XibCollectionViewCell
XibCollectionViewCell

UICollectionView分组

效果图

采用的是xib的方式创建的CollectionViewCell

结构 Xib
  • XibCollectionReusableView
XibCollectionReusableView
  • ViewController
import UIKit

class ViewController: UIViewController {
    //MARK: - 属性
    //继承关系:UICollectionView -> UIScrollView
    var collectionView:UICollectionView? = nil
    override func viewDidLoad() {
        super.viewDidLoad()
        //1.创建UICollectionView子类对象(layout类型的都型,一般使用UICollectionViewFlowLayout)
        //作用:专门负责CollectionView的布局
        let layout = UICollectionViewFlowLayout()
        
        //设置cell的大小(这种方式设置的每个cell的大小是相同的,想要不同,就在delegate里面设置)
        //layout.itemSize = CGSizeMake(100, 150)
        
        //=====================
        
        //设置每个cell之间的间距(行间距和列间距)
        layout.minimumLineSpacing = 0 //设置这个属性就是直接设置了每一行cell之间的间距
        layout.minimumInteritemSpacing = 0 //设置这个属性就是直接设置了列间距
        //设置滚动方向(默认上下滚动)
        //layout.scrollDirection = .Horizontal
        
        //=====================
        
        //2.创建UICollectionView对象
        //参数2:
        self.collectionView = UICollectionView(frame: self.view.bounds, collectionViewLayout: layout)
        //3.添加到界面
        self.view.addSubview(self.collectionView!)
        //4.设置背景颜色
        self.collectionView?.backgroundColor = UIColor.whiteColor()
        //5.设置代理
        self.collectionView?.dataSource = self
        self.collectionView?.delegate = self
        
        //************
        //6.注册cell
        //注册Xib创建的cell
        //self.collectionView?.registerNib(<#T##nib: UINib?##UINib?#>, forCellWithReuseIdentifier: <#T##String#>)
        //注册手写的cell或系统cell
        //参数1:cell类型
        //参数2:ID
        self.collectionView?.registerClass(UICollectionViewCell.self, forCellWithReuseIdentifier: "cell")
        
        //************
        //注册view
        //注册手写或系统的view
        //self.collectionView?.registerClass(UICollectionReusableView.self, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "view")
        //注册Xib写的view
        self.collectionView?.registerNib(UINib(nibName: "XibCollectionReusableView", bundle: nil), forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "view")
    }
}

extension ViewController:UICollectionViewDataSource{
    //设置每个分组的cell个数(不分组的话默认分组数为1)
    func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        switch section{
        case 0:return 7
        case 1:return 3
        default:return 5
        }
    }
    //创建cell
    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        //1.去复用池中查找是否有可以复用的cell,如过找到就返回那个可以复用的cell,没有就 <自动创建> 一个新的cell返回(在这之前必须去注册cell)
        //参数1:ID
        //参数2:
        let cell = collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath)
        //2.刷新数据
        cell.backgroundColor = UIColor(red: CGFloat(arc4random() % 256) / 255, green: CGFloat(arc4random() % 256) / 255, blue: CGFloat(arc4random() % 256) / 255, alpha: 1)
        return cell
    }
    
    //设置分组数
    func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int{
        return 3
    }
    
//MARK: - 创建headerView
    
    //设置headerView和footerView
    //参数2:类型 -> 标识当前设置的是headerView还是footerView
    //参数3:indexPath的位置
    //返回值:创建好的headerView或者footerView
    func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView {
        //UICollectionReusableView中创建headerView的过程和创建cell基本一样
        
        //1.去复用池中查找是否有可复用的headerView,找不到就新建
        //在使用这个方法之前要像注册cell一样注册view
        //参数:确定当前要创建的是headerView还是footerView
        //UICollectionElementKindSectionHeader -> header
        //UICollectionElementKindSectionFooter -> footer
        //参数2:复用ID
        //参数3:创建的header/footer位置
        //系统
        //let reuseView = collectionView.dequeueReusableSupplementaryViewOfKind(UICollectionElementKindSectionHeader, withReuseIdentifier: "view", forIndexPath: indexPath)
        //Xib
        let reuseView = collectionView.dequeueReusableSupplementaryViewOfKind(UICollectionElementKindSectionHeader, withReuseIdentifier: "view", forIndexPath: indexPath) as? XibCollectionReusableView
        //2.刷新数据
        
        //reuseView!.backgroundColor = UIColor.redColor()
        let titles = ["周星驰","经典电影","每一分钟"]
        reuseView?.titleLabel.text = titles[indexPath.section]
        return reuseView!
    }
}

// MARK: - UICollectionViewDelegateFlowLayout

//UICollectionViewDelegateFlowLayout遵守了UICollectionViewDelegate协议,UICollectionViewDelegate遵守了UIScrollViewDelegate
extension ViewController:UICollectionViewDelegateFlowLayout{
    //设置每个cell的大小
    //可以让不同分组设置不同的大小
    //indexPath -> cell的位置
    //indexPath.section -> 组
    //indexPath.item -> 个
    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
        //方案1:确定每个cell的大小,和每一行cell的个数去计算间距
        //return CGSizeMake(100, 150)
        //方案2:确定每个cell的间距,和每一行cell的个数,去计算cell的大小
        let width = self.view.bounds.width / 4
        return CGSizeMake(width, 150)
    }
    
    //设置每个分组到CollectionView上下左右的间距
    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAtIndex section: Int) -> UIEdgeInsets {
        //方案1对应设置:确定每个cell的大小,和每一行cell的个数去计算间距
        //let margin = (self.view.bounds.width - 100 * 3) / 4
        //return UIEdgeInsetsMake(margin, margin, margin, margin)
        //方案2对应设置:确定每个cell的间距,和每一行cell的个数,去计算cell的大小
        return UIEdgeInsetsMake(0, 0, 20, 0)
    }
    
    //MARK: - 设置header的大小
    
    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize{
        return CGSizeMake(300, 40)
    }
}

相关文章

网友评论

      本文标题:UICollectionView

      本文链接:https://www.haomeiwen.com/subject/mgpuettx.html