iOS

前言

	NS_CLASS_AVAILABLE_IOS(6_0) @interface UICollectionView : UIScrollView
	@available(iOS 6.0, *)		 public class UICollectionView : UIScrollView 

1、collectionView 的创建

  • Objective-C

    • ViewController.m

      • 遵守协议 UICollectionViewDataSource, UICollectionViewDelegate
      	// 数据源初始化
      		
      		// 声明数据源
      		@property(nonatomic, retain)NSMutableArray *myDataArray;
      		
      		myDataArray = [[NSMutableArray alloc] init];
      		    
      		NSMutableArray *titleNameArray = [[NSMutableArray alloc] init];
      		NSMutableArray *imageNameArray = [[NSMutableArray alloc] init];
      		    
      		for (int i = 1; i <= 15; i++) {
      		    
      		    [titleNameArray addObject:[NSString stringWithFormat:@"第 %i 个", i]];
      		    [imageNameArray addObject:[NSString stringWithFormat:@"2_%i", i]];
      		}
      		    
      		[myDataArray addObject:titleNameArray];
      		[myDataArray addObject:imageNameArray];
      
      	// 网格视图初始化
      	
      		// 创建网格视图布局对象,可以设置滑动方向,cell 的间距等
      		UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
      	
      		// 创建网格视图对象,必须有布局对象
      		UICollectionView *collectionView = [[UICollectionView alloc] 
      		                          initWithFrame:CGRectMake(0, 20, self.view.bounds.size.width, 
      		                                                          self.view.bounds.size.height - 20) 
      		                   collectionViewLayout:flowLayout];
      		                   
      		// 设置代理
      		collectionView.dataSource = self;
      		collectionView.delegate = self;
      		    
      		// 将网格视图添加到屏幕视图
      		[self.view addSubview:collectionView];
      
      		// 注册自定义表格视图
      		[collectionView registerClass:[myCollectionViewCell1 class] forCellWithReuseIdentifier:@"myCell"];
      
      	// UICollectionView 协议方法
      		
      		// 设置网格数
      		- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
      		    
      			return [[myDataArray objectAtIndex:0] count];
      		}
      		
      		// 设置网格大小
      		- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)
      			indexPath {
      		    
      		   	return CGSizeMake((self.view.bounds.size.width - 40) / 3, 170);
      		}
      		
      		// 设置每个网格的内容
      		- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
      		    
      		    // 使用自定义 Cell 创建,cell 必须用注册的方式定义
      		    myCollectionViewCell1 *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"myCell" forIndexPath:indexPath];
      		    
      		    // 设置 Cell 中视图包含的内容
      		    cell.nameLabel.text = [myDataArray[0] objectAtIndex:indexPath.item];
      		    cell.iconImageView.image = [UIImage imageNamed:[myDataArray[1] objectAtIndex:indexPath.item]];
      		    
      		    return cell;
      		}
      
    • myCollectionViewCell.h

      	@interface myCollectionViewCell1 : UICollectionViewCell
      
      	@property(nonatomic, retain)UILabel *nameLabel;
      	@property(nonatomic, retain)UIImageView *iconImageView;
      
      	@end
      
    • myCollectionViewCell.m

      	- (instancetype)initWithFrame:(CGRect)frame {
          
      		self = [super initWithFrame:frame];
          
      		if (self) {
              
      			// 创建标签视图
              	_nameLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.bounds.size.width, 20)];
              	_nameLabel.backgroundColor = [UIColor orangeColor];
              	_nameLabel.textAlignment = NSTextAlignmentCenter;
              	[self.contentView addSubview:_nameLabel];
              
              	// 创建图片视图
              	_iconImageView = [[UIImageView alloc] 
              	                           initWithFrame:CGRectMake(0, 20, self.bounds.size.width, 
              	                                                           self.bounds.size.height - 20)];
              	[self.contentView addSubview:_iconImageView];
      		}
      		return self;
      	}
      
  • Swift

    • ViewController.swift

      • 遵守协议 UICollectionViewDataSource, UICollectionViewDelegate
      	// 数据源初始化
      	
      		// 声明数据源
      		var dataArray:[[String]] = Array()
      		    
      		var titleNameArray:[String] = Array()
      		var imageNameArray:[String] = Array()
      		    
      		for i in 1...15 {
      		    
      		    titleNameArray.append("第 (i) 个")
      		    imageNameArray.append("2_(i)")
      		}
      		    
      		dataArray.append(titleNameArray)
      		dataArray.append(imageNameArray)
          
      	// 网格视图初始化
      
      		// 创建网格视图布局对象,可以设置滑动方向,cell 的间距等
      		let flowLayout = UICollectionViewFlowLayout()
      		    
      		// 创建网格视图对象,必须有布局对象
      		let collectionView = UICollectionView(frame: CGRectMake(0, 20, self.view.bounds.size.width, 
      		                                                               self.view.bounds.size.height - 20), 
      		                       collectionViewLayout: flowLayout)
      		    
      		// 设置代理
      		collectionView.dataSource = self
      		collectionView.delegate = self
      		    
      		// 将网格视图添加到屏幕视图
      		self.view.addSubview(collectionView)
      
      		// 注册自定义表格视图
      		collectionView.registerClass(myCollectionViewCell1.self, forCellWithReuseIdentifier: "myCell")
      		
      	// UICollectionView 协议方法
      		    
      		// 设置网格数
      		func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
      		    
      		  	return dataArray[0].count
      		}
      		    
      		// 设置网格大小
      		func collectionView(collectionView: UICollectionView!, layout collectionViewLayout: UICollectionViewLayout!, sizeForItemAtIndexPath indexPath: 							NSIndexPath!) -> CGSize{
      		    
      		  	return CGSizeMake((self.view.bounds.size.width - 40) / 3, 170)
      		}
      		    
      		// 设置每个网格的内容,cell 必须用注册方式定义
      		func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
      		 	
      		 	// 使用自定义 Cell 创建
      		   	let cell = collectionView.dequeueReusableCellWithReuseIdentifier("myCell", forIndexPath: indexPath) as! myCollectionViewCell1
      		   
      		   	// 设置 Cell 视图的内容
      		   	cell.nameLabel.text = dataArray[0][indexPath.item]
      		   	cell.iconImageView.image = UIImage(named: dataArray[1][indexPath.item])
      		    
      		   	return cell
      		}
      
    • myCollectionViewCell.swift

      	class myCollectionViewCell1: UICollectionViewCell {
          
          	var nameLabel:UILabel!
          	var iconImageView:UIImageView!
          
          	override init(frame: CGRect) {
              
              	super.init(frame: frame)
              
              	// 创建标签视图
              	nameLabel = UILabel(frame: CGRectMake(0, 0, self.frame.size.width, 20))
              	nameLabel.backgroundColor = UIColor.orangeColor()
              	nameLabel.textAlignment = NSTextAlignment.Center
              	self.contentView.addSubview(nameLabel)
              
              	// 创建图片视图
              	iconImageView = UIImageView(frame: CGRectMake(0, 20, self.frame.size.width, 
              	                                                     self.frame.size.height - 20))
              	self.contentView.addSubview(iconImageView)
          	}
      	}
      

2、collectionView 的设置

  • Objective-C

    	// 设置表格滑动方向
      	/*
    		UICollectionViewScrollDirectionVertical       垂直方向,默认
    		UICollectionViewScrollDirectionHorizontal     水平方向
    	*/
     	flowLayout.scrollDirection = UICollectionViewScrollDirectionVertical;
        
    	// 设置网格最小水平和垂直方向间距
    	/*
    		默认 10,也可以通过代理设置
    	*/
      	flowLayout.minimumInteritemSpacing = 5;
    	flowLayout.minimumLineSpacing = 30;
        
    	// 设置网格背景颜色
    	/*
    		默认为黑色
    	*/
    	collectionView.backgroundColor = [UIColor clearColor];
    
  • Swift

    	// 设置表格滑动方向
    	/*
    		case Vertical     垂直方向,默认
    		case Horizontal   水平方向
    	*/
    	flowLayout.scrollDirection = UICollectionViewScrollDirection.Vertical
        
    	// 设置网格最小水平和垂直方向间距
    	/*
    		默认 10,也可以通过代理设置
    	*/
    	flowLayout.minimumInteritemSpacing = 5
    	flowLayout.minimumLineSpacing = 30
        
    	// 设置网格背景颜色
    	/*
    		默认为黑色
    	*/
    	collectionView.backgroundColor = UIColor.clearColor()
    

3、自定义 Cell 的创建与引用

  • Objective-C

    • myCollectionViewCell.h

      	@interface myCollectionViewCell1 : UICollectionViewCell
      
      	@property(nonatomic, retain)UILabel *nameLabel;
      	@property(nonatomic, retain)UIImageView *iconImageView;
      
      	@end
      
    • myCollectionViewCell.m

      	- (instancetype)initWithFrame:(CGRect)frame {
          
          	self = [super initWithFrame:frame];
          
          	if (self) {
              
              	// 创建标签视图
              	_nameLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.bounds.size.width, 20)];
              	_nameLabel.backgroundColor = [UIColor orangeColor];
              	_nameLabel.textAlignment = NSTextAlignmentCenter;
              	[self.contentView addSubview:_nameLabel];
              
              	// 创建图片视图
              	_iconImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 20, 
              	                                   self.bounds.size.width, self.bounds.size.height - 20)];
              	[self.contentView addSubview:_iconImageView];
          	}
          	return self;
      	}
      
    • ViewController.m

      	// 注册自定义表格视图
      	[collectionView registerClass:[myCollectionViewCell1 class] forCellWithReuseIdentifier:@"myCell"];
      
      	// 设置网格大小
      	- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)
      	indexPath {
      
      		return CGSizeMake((self.view.bounds.size.width - 40) / 3, 170);
      	}
      
      	// 设置每个网格的内容,cell 必须采用注册的方式自定义
      	- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
      
      		// 使用自定义 Cell 创建
      		myCollectionViewCell1 *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"myCell" forIndexPath:indexPath];
      
      		// 设置自定义 Cell 中视图包含的内容
      		cell.nameLabel.text = [myDataArray[0] objectAtIndex:indexPath.item];
      		cell.iconImageView.image = [UIImage imageNamed:[myDataArray[1] objectAtIndex:indexPath.item]];
      
      		return cell;
      	}
      
  • Swift

    • myCollectionViewCell.swift

      	class myCollectionViewCell1: UICollectionViewCell {
          
          	var nameLabel:UILabel!
          	var iconImageView:UIImageView!
          
          	override init(frame: CGRect) {
              
              	super.init(frame: frame)
              
              	// 创建标签视图
              	nameLabel = UILabel(frame: CGRectMake(0, 0, self.frame.size.width, 20))
              	nameLabel.backgroundColor = UIColor.orangeColor()
              	nameLabel.textAlignment = NSTextAlignment.Center
              	self.contentView.addSubview(nameLabel)
              
              	// 创建图片视图
              	iconImageView = UIImageView(frame: CGRectMake(0, 20, self.frame.size.width, 
              	                                                     self.frame.size.height - 20))
              	self.contentView.addSubview(iconImageView)
          	}	
      	}
      
    • ViewController.swift

      	// 注册自定义表格视图
      	collectionView.registerClass(myCollectionViewCell1.self, forCellWithReuseIdentifier: "myCell")
      
      	// 设置网格大小
      	func collectionView(collectionView: UICollectionView!, layout collectionViewLayout: UICollectionViewLayout!, sizeForItemAtIndexPath indexPath: NSIndexPath!) -> 			CGSize{
              
      		return CGSizeMake((self.view.bounds.size.width - 40) / 3, 170)
      	}
          
      	// 设置每个网格的内容,cell 必须用注册方式定义
      	func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
           	
        	// 使用自定义 Cell 创建
        	let cell = collectionView.dequeueReusableCellWithReuseIdentifier("myCell", forIndexPath: indexPath) as! myCollectionViewCell1   
              
          	// 设置 Cell 视图的内容
      		cell.nameLabel.text = dataArray[0][indexPath.item]
      		cell.iconImageView.image = UIImage(named: dataArray[1][indexPath.item])
              
      		return cell
      	}
      

4、xib 自定义 Cell 的创建与引用

  • Objective-C

    • myCollectionViewCell.xib

    CollectionView1

    • myCollectionViewCell.h

      	@interface myCollectionViewCell : UICollectionViewCell
      
      	@property (weak, nonatomic) IBOutlet UILabel *nameLabel;
      	@property (weak, nonatomic) IBOutlet UIImageView *iconImageView;
      
      	@end
      
    • ViewController.m

      	// 注册自定义表格视图
      	[collectionView registerNib:[UINib nibWithNibName:@"myCollectionViewCell3" bundle:nil] forCellWithReuseIdentifier:@"xibCell"];
      
      	// 设置网格大小
      	- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)
      	indexPath {
          
          	return CGSizeMake(100, 170);
      	}
      
      	// 设置每个网格的内容,cell 必须采用注册的方式自定义
      	- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
          
          	// 使用自定义 Cell 创建
          	myCollectionViewCell3 *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"xibCell" forIndexPath:indexPath];
          
          	// 设置自定义 Cell 中视图包含的内容
          	cell.nameLabel.text = [dataArray[0] objectAtIndex:indexPath.item];
          	cell.iconImageView.image = [UIImage imageNamed:[dataArray[1] objectAtIndex:indexPath.item]];
          
          	return cell;
      	}
      
  • Swift

    • myCollectionViewCell.xib

    CollectionView1

    • myCollectionViewCell.swift

      	class myCollectionViewCell: UICollectionViewCell {
      
          	@IBOutlet weak var nameLabel: UILabel!
          	@IBOutlet weak var iconImageView: UIImageView!
      	}
      
    • ViewController.swift

      	// 注册自定义表格视图
      	collectionView.registerNib(UINib(nibName: "myCollectionViewCell3", bundle: nil), forCellWithReuseIdentifier: "xibCell")
      	
      	// 设置网格大小
      	func collectionView(collectionView: UICollectionView!, layout collectionViewLayout: UICollectionViewLayout!, sizeForItemAtIndexPath indexPath: NSIndexPath!) -> 			CGSize{
          
          	return CGSizeMake(100, 170)
      	}
      
      	// 设置每个网格的内容,cell 必须用注册的方式定义
      	func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
          
          	// 使用自定义 Cell 创建
          	let cell = collectionView.dequeueReusableCellWithReuseIdentifier("xibCell", forIndexPath: indexPath) as! myCollectionViewCell3
          
          	// 设置 Cell 视图内容
          	cell.nameLabel.text = dataArray[0][indexPath.item]
          	cell.iconImageView.image = UIImage(named: dataArray[1][indexPath.item])
          
          	return cell
      	}
      

5、自定义 分段头尾的创建与引用

  • Objective-C

    • myHeaderFooterView.h

      	@interface myHeaderFooterView : UICollectionReusableView
      
      	@property(nonatomic, retain)UILabel *nameLabel;
      
      	@end
      
    • myHeaderFooterView.m

      	- (instancetype)initWithFrame:(CGRect)frame {
          
          	self = [super initWithFrame:frame];
          
          	if (self) {
              
              	_nameLabel = [[UILabel alloc] initWithFrame:self.bounds];
              	_nameLabel.textAlignment = NSTextAlignmentCenter;
              	_nameLabel.backgroundColor = [UIColor lightGrayColor];
              
              	[self addSubview:_nameLabel];
          	}
          	return self;
      	}
      
    • ViewController.m

      	// 注册分段头视图
      	[collectionView registerClass:[myHeaderFooterView1 class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"header"];
      
      	// 注册分段尾视图
      	[collectionView registerClass:[myHeaderFooterView1 class] forSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:@"footer"];
      
      	// 设置分段头大小
      	- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)
      	section {
          
          	/*
              	width 为水平滑动时,间距有效。height 为垂直滑动时,间距有效。
           	*/
          	return CGSizeMake(20, 30);
      	}
      
      	// 设置分段尾大小
      	- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)
      	section {
          
          	/*
              	width 为水平滑动时,间距有效。height 为垂直滑动时,间距有效。
           	*/
          	return CGSizeMake(20, 30);
      	}
      
      	// 设置分段头尾的内容
      	- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)
      	indexPath {
          
          	// collectionView 分段头尾的设置注册复用
          	myHeaderFooterView1 *view = nil;
          
          	// 分段头
          	if (kind == UICollectionElementKindSectionHeader) {
              
              	// 创建分段头视图
              	view = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"header" forIndexPath:indexPath];
              
              	// 设置分段头的内容
              	view.nameLabel.text = [NSString stringWithFormat:@"第 %ld 段 Header", indexPath.section];
          	}
          	// 分段尾
          	else {                                                                                                      
              
              	// 创建分段尾视图
              	view = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:@"footer" forIndexPath:indexPath];
      
              	// 设置分段尾视图的内容
              	view.nameLabel.text = [NSString stringWithFormat:@"第 %ld 段结束 Footer", indexPath.section];
          	}
          
          	return view;
      	}
      
  • Swift

    • myHeaderFooterView.swift

      	class myHeaderFooterView: UICollectionReusableView {
          
          	var nameLabel:UILabel!
          
          	override init(frame: CGRect) {
              
              	super.init(frame: frame)
              
              	nameLabel = UILabel(frame: self.bounds)
              	nameLabel.textAlignment = NSTextAlignment.Center
              	nameLabel.backgroundColor = UIColor.lightGrayColor()
              
              	self.addSubview(nameLabel)
          	}
      	}
      
    • ViewController.swift

      	// 注册分段头视图
      	collectionView.registerClass(myHeaderFooterView1.self, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "header")
      
      	// 注册分段尾视图
      	collectionView.registerClass(myHeaderFooterView1.self, forSupplementaryViewOfKind: UICollectionElementKindSectionFooter, withReuseIdentifier: "footer")
      
      	// 设置分段头大小
      	func collectionView(collectionView: UICollectionView!, layout collectionViewLayout: UICollectionViewLayout!, referenceSizeForHeaderInSection:section) -> CGSize  			{
          
          	/*
              	width 为水平滑动时,间距有效。height 为垂直滑动时,间距有效。
           	*/
          
          	return CGSizeMake(20, 30)
      	}
      
      	// 设置分段尾大小
      	func collectionView(collectionView: UICollectionView!, layout collectionViewLayout: UICollectionViewLayout!, referenceSizeForFooterInSection:section) -> CGSize  		{
          
          	/*
              	width 为水平滑动时,间距有效。height 为垂直滑动时,间距有效。
           	*/
          
          return CGSizeMake(20, 30)
      	}
      
      	// 设置分段头尾的内容
      	func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> 							UICollectionReusableView {
          
          	var view:myHeaderFooterView1!
          
          	// 分段头
          	if kind == UICollectionElementKindSectionHeader {
              
              	// 创建分段头视图
              	view = collectionView.dequeueReusableSupplementaryViewOfKind(UICollectionElementKindSectionHeader, withReuseIdentifier: "header", forIndexPath:indexPath) as! myHeaderFooterView1
              
              	// 设置分段头的内容
             		view.nameLabel.text = "第 (indexPath.section) 段 Header"
          	}
          	// 分段尾
          	else {
              	// 创建分段尾视图
              	view = collectionView.dequeueReusableSupplementaryViewOfKind(UICollectionElementKindSectionFooter, withReuseIdentifier: "footer", forIndexPath:indexPath) as! myHeaderFooterView1
              	
              	// 设置分段尾视图的内容
              	view.nameLabel.text = "第 (indexPath.section) 段 Footer"
          	}
          	
          	return view
      	}
      

6、xib 自定义 分段头尾的创建与引用

  • Objective-C

    • myHeaderFooterView.xib

      CollectionView2

    • myHeaderFooterView.h

      	@interface myHeaderFooterView : UICollectionReusableView
      
      	@property (weak, nonatomic) IBOutlet UILabel *nameLabel;
      
      	@end
      
    • ViewController.m

      	// 注册分段头视图
      	[collectionView registerNib:[UINib nibWithNibName:@"myHeaderFooterView2" bundle:nil] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"xibHeader"];
      
      	// 注册分段尾视图
      	[collectionView registerNib:[UINib nibWithNibName:@"myHeaderFooterView2" bundle:nil] forSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:@"xibFooter"];
      
      	// 设置分段头大小
      	- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section {
          
          	/*
            		width 为水平滑动时,间距有效。height 为垂直滑动时,间距有效。
           	*/
          	return CGSizeMake(20, 30);
      	}
      
      	// 设置分段尾大小
      	- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section {
          
          	/*
              	width 为水平滑动时,间距有效。height 为垂直滑动时,间距有效。
           	*/
          	return CGSizeMake(20, 30);
      	}
      
      	// 设置分段头尾的内容
      	- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath {
          
          	// collectionView 分段头尾的设置注册复用
          	myHeaderFooterView2 *view = nil;
          
          	// 分段头
          	if (kind == UICollectionElementKindSectionHeader) {
              
             	// 创建分段头视图
              view = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"xibHeader" forIndexPath:indexPath];
              
              	// 设置分段头的内容
              	view.nameLabel.text = [NSString stringWithFormat:@"第 %ld 段 xibHeader", indexPath.section];
          	}
          	// 分段尾
          	else {
              
              	// 创建分段尾视图
              	view = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:@"xibFooter" forIndexPath:indexPath];
              
              	// 设置分段尾视图的内容
              	view.nameLabel.text = [NSString stringWithFormat:@"第 %ld 段结束 xibFooter", indexPath.section];
          	}
          
          	return view;
      	}
      
  • Swift

    • myHeaderFooterView.xib

      CollectionView2

    • myHeaderFooterView.swift

      	class myHeaderFooterView: UICollectionReusableView {
      
      		@IBOutlet weak var nameLabel: UILabel!
      	}
      
    • ViewController.swift

      	// 注册分段头视图
      	collectionView.registerNib(UINib(nibName: "myHeaderFooterView2", bundle: nil), forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "xibHeader")
      
      	// 注册分段尾视图
      	collectionView.registerNib(UINib(nibName: "myHeaderFooterView2", bundle: nil), forSupplementaryViewOfKind: UICollectionElementKindSectionFooter, 												withReuseIdentifier: "xibFooter")
      
      	// 设置分段头大小
      	func collectionView(collectionView: UICollectionView!, layout collectionViewLayout: UICollectionViewLayout!, referenceSizeForHeaderInSection:section) -> CGSize {
          
          	/*
              	width 为水平滑动时,间距有效。height 为垂直滑动时,间距有效。
           	*/
          
          	return CGSizeMake(20, 30)
      	}
      
      	// 设置分段尾大小
      	func collectionView(collectionView: UICollectionView!, layout collectionViewLayout: UICollectionViewLayout!, referenceSizeForFooterInSection:section) -> CGSize {
          
          	/*
              	width 为水平滑动时,间距有效。height 为垂直滑动时,间距有效。
           	*/
          
          	return CGSizeMake(20, 30)
      	}
      
      	// 设置分段头尾的内容
      
      	func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView {
          
          	var view:myHeaderFooterView2!
          
          	// 分段头
          	if kind == UICollectionElementKindSectionHeader {
              
              	// 创建分段头视图
              	view = collectionView.dequeueReusableSupplementaryViewOfKind(UICollectionElementKindSectionHeader, withReuseIdentifier: "xibHeader", forIndexPath:indexPath) as! myHeaderFooterView2
              
              	// 设置分段头的内容
              	view.nameLabel.text = "第 (indexPath.section) 段 Header"
          	}
          	// 分段尾
          	else {
              
              	// 创建分段尾视图
              	view = collectionView.dequeueReusableSupplementaryViewOfKind(UICollectionElementKindSectionFooter, withReuseIdentifier: "xibFooter", forIndexPath:indexPath) as! myHeaderFooterView2
      
              	// 设置分段尾视图的内容
              	view.nameLabel.text = "第 (indexPath.section) 段 Footer"                                            
          	}
          
          	return view
      	}
      

7、自定义布局风格

  • Objective-C

    • CustomLayout.h

      	@interface CustomLayout : UICollectionViewLayout
      
    • CustomLayout.m

      	/*
          	简单定义了一个 section 的布局
       	*/
      
      	@implementation CustomLayout
      
      	// 设置网格视图的大小
      	- (CGSize)collectionViewContentSize {
          
          	// 每行显示 3 个图标,1大2小
          	return CGSizeMake(self.collectionView.bounds.size.width, [self.collectionView numberOfItemsInSection:0 / 3] * 200 + 200);
      	}
      
      	// 设置单元格的位置属性
      	- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect {
          
          	NSMutableArray *attributesArray = [[NSMutableArray alloc] init];
          
          	NSUInteger cellCount = [self.collectionView numberOfItemsInSection:0];
          
          	for (int i = 0; i < cellCount; i++) {
              
              	UICollectionViewLayoutAttributes *attributes = [self layoutAttributesForItemAtIndexPath:[NSIndexPath indexPathForItem:i inSection:0]];
              
              	[attributesArray addObject:attributes];
          	}
          	return attributesArray;
      	}
      
      	// 设置单元格的位置与大小
      	- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath {
          
          	// 获取当前单元格布局属性
          	UICollectionViewLayoutAttributes *attribute = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
          
          	// 单元格边长
          	CGFloat largeCellSide = 200;
          	CGFloat smallCellSide = 100;
          
          	// 单元格间距
          	//    NSUInteger itemSpacing = 2;
          	NSUInteger lineSpacing = 5;
          
          	// 边距
          	UIEdgeInsets insets = UIEdgeInsetsMake(2, 20, 2, 20);
          
          	// 当前行数
          	/*
          		每行显示 3 个图片,1 大 2 小
          	*/
          	NSInteger line = indexPath.item / 3;
          
          	// 当前行的 Y 坐标
          	CGFloat lineOriginY = insets.top + largeCellSide * line + lineSpacing * line;
          
          	// 右侧单元格 X 坐标
          	/*
          		这里按左右对齐,所以中间空隙大
          	*/
          	CGFloat rightLargeX = self.collectionView.bounds.size.width - largeCellSide - insets.right;
          	CGFloat rightSmallX = self.collectionView.bounds.size.width - smallCellSide - insets.right;
          
          	// 每行 2 个图片,2 行循环一次,一共 6 种位置
          	if (indexPath.item % 6 == 0) {
              
              	attribute.frame = CGRectMake(insets.left, lineOriginY, largeCellSide, largeCellSide);
          	}
          	else if (indexPath.item % 6 == 1) {
              
              	attribute.frame = CGRectMake(rightSmallX, lineOriginY, smallCellSide, smallCellSide);
          	}
          	else if (indexPath.item % 6 == 2) {
              
              	attribute.frame = CGRectMake(rightSmallX, lineOriginY + smallCellSide + insets.top, smallCellSide, smallCellSide);
          	}
          	else if (indexPath.item % 6 == 3) {
              
              	attribute.frame = CGRectMake(insets.left, lineOriginY, smallCellSide, smallCellSide);
          	}
          	else if (indexPath.item % 6 == 4) {
              
              	attribute.frame = CGRectMake(insets.left, lineOriginY + smallCellSide + insets.top, smallCellSide, smallCellSide);
          	}
          	else if (indexPath.item % 6 == 5) {
              
              	attribute.frame = CGRectMake(rightLargeX, lineOriginY, largeCellSide, largeCellSide);
          	}
          
          	return attribute;
      	}
      
    • ViewController.m

      	// 数据源初始化
      
      		// 声明数据源
      		@property(nonatomic, retain)NSMutableArray *dataArray;
      
          	dataArray = [NSMutableArray arrayWithObjects:   @{@"name":@"Swift" , @"pic":@"swift.png" },
                       	@{@"name":@"OC"    , @"pic":@"oc.jpg"    },
                       	@{@"name":@"Java"  , @"pic":@"java.png"  },
                       	@{@"name":@"PHP"   , @"pic":@"php.jpeg"  },
                       	@{@"name":@"JS"    , @"pic":@"js.jpeg"   },
                       	@{@"name":@"HTML"  , @"pic":@"html.jpeg" },
                       	@{@"name":@"Ruby"  , @"pic":@"ruby.png"  }, nil];
      
      	// 网格视图初始化
      
      		// 声明网格视图
      		@property(nonatomic, retain)UICollectionView *myCollectionView;
      
          	CustomLayout *layout = [[CustomLayout alloc] init];
          
          	myCollectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 20, self.view.bounds.size.width, self.view.bounds.size.height - 20) collectionViewLayout:layout];
          	
          	// 默认背景是黑色和 label 一致
          	myCollectionView.backgroundColor = [UIColor whiteColor];
          	myCollectionView.delegate = self;
          	myCollectionView.dataSource = self;
          
          	// 注册 CollectionViewCell
          	[myCollectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"myCell"];
          
          	[self.view addSubview:myCollectionView];
      
      	// UICollectionView 协议方法
      
          	// 设置行数
          	- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
              
              	return dataArray.count;
          	}
      
          	// 设置网格显示的内容
          	- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
              
              	// 创建 cell
              	UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"myCell" forIndexPath:indexPath];
              
              	// 创建自定义 cell 视图
              	UIImageView *imageView = [[UIImageView alloc] initWithFrame:cell.bounds];
              	imageView.image = [UIImage imageNamed:dataArray[indexPath.item][@"pic"]];
              	[cell addSubview:imageView];
              
              	UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 5, cell.bounds.size.width, 20)];
              	label.text = dataArray[indexPath.item][@"name"];
              	label.textAlignment = NSTextAlignmentCenter;
              	[cell addSubview:label];
              
              	return cell;
          	}
      
  • Swift

    • CustomLayout.swift

      	/*
      		简单定义了一个 section 的布局
       	*/
      
      	class CustomLayout: UICollectionViewLayout
      
      	// 设置网格视图的大小
      	override func collectionViewContentSize() -> CGSize {
          
          	// 每行显示 3 个图标,1大2小
          	return CGSizeMake(collectionView!.bounds.size.width, CGFloat((collectionView!.numberOfItemsInSection(0) / 3) * 200 + 200))
      	}
      
      	// 设置单元格的位置属性
      	override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
      
          	var attributesArray = Array<UICollectionViewLayoutAttributes>()
          
          	let cellCount = self.collectionView!.numberOfItemsInSection(0)
          
          	for i in 0..<cellCount {
              
              	let attributes = self.layoutAttributesForItemAtIndexPath(NSIndexPath(forItem: i, inSection: 0))
              
              	attributesArray.append(attributes!)
          	}
          
          	return attributesArray
      	}
      
      	// 设置单元格的位置与大小
      	override func layoutAttributesForItemAtIndexPath(indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes? {
          
          	// 获取当前单元格布局属性
          	let attribute = UICollectionViewLayoutAttributes(forCellWithIndexPath:indexPath)
          
          	// 单元格边长
          	let largeCellSide = CGFloat(200)
          	let smallCellSide = CGFloat(100)
          
          	// 单元格间距
          	let itemSpacing = 2
          	let lineSpacing = 5
          
          	// 边距
          	let insets = UIEdgeInsetsMake(2, 20, 2, 20)
          
          	// 当前行数
          	/*
          		每行显示 3 个图片,1 大 2 小
          	*/
          	let line = indexPath.item / 3
          
          	// 当前行的 Y 坐标
          	let lineOriginY = insets.top + largeCellSide * CGFloat(line) + CGFloat(lineSpacing * line)
          
          	// 右侧单元格 X 坐标
          	/*
          		这里按左右对齐,所以中间空隙大
          	*/
          	let rightLargeX = collectionView!.bounds.size.width - largeCellSide - insets.right
          	let rightSmallX = collectionView!.bounds.size.width - smallCellSide - insets.right
          
          	// 每行 2 个图片,2 行循环一次,一共 6 种位置
          	if (indexPath.item % 6 == 0) {
              
              	attribute.frame = CGRectMake(insets.left, lineOriginY, largeCellSide, largeCellSide)
          	}
          	else if (indexPath.item % 6 == 1) {
              
              	attribute.frame = CGRectMake(rightSmallX, lineOriginY, smallCellSide, smallCellSide)
          	}
          	else if (indexPath.item % 6 == 2) {
              
              	attribute.frame = CGRectMake(rightSmallX, lineOriginY + smallCellSide + insets.top, smallCellSide, smallCellSide)
          	}
          	else if (indexPath.item % 6 == 3) {
              
              	attribute.frame = CGRectMake(insets.left, lineOriginY, smallCellSide, smallCellSide)
          	}
          	else if (indexPath.item % 6 == 4) {
              
              	attribute.frame = CGRectMake(insets.left, lineOriginY + smallCellSide + insets.top, smallCellSide, smallCellSide)
          	}
          	else if (indexPath.item % 6 == 5) {
              
              	attribute.frame = CGRectMake(rightLargeX, lineOriginY, largeCellSide, largeCellSide)
          	}
          
          	return attribute
      	}
      
    • ViewController.swift

      	// 数据源初始化
      
      		// 声明数据源
      		var dataArray:[[String:String]] = Array()
      
          	dataArray = [
              
              	["name":"Swift" , "pic":"swift.png" ],
              	["name":"OC"    , "pic":"oc.jpg"    ],
              	["name":"Java"  , "pic":"java.png"  ],
              	["name":"PHP"   , "pic":"php.jpeg"  ],
              	["name":"JS"    , "pic":"js.jpeg"   ],
              	["name":"HTML"  , "pic":"html.jpeg" ],
              	["name":"Ruby"  , "pic":"ruby.png"  ]
          	]
      
      	// 网格视图初始化
      
      		var myCollectionView:UICollectionView!
      
      	// 声明网格视图
      
          	let layout = CustomLayout()
          
          	myCollectionView = UICollectionView(frame: CGRectMake(0, 20, self.view.bounds.size.width, self.view.bounds.size.height - 20), 
          	                     collectionViewLayout:layout)
          	
          	// 默认背景是黑色和 label 一致
          	myCollectionView.backgroundColor = UIColor.whiteColor()
          	myCollectionView.delegate = self
          	myCollectionView.dataSource = self
          
          	// 注册 CollectionViewCell
          	myCollectionView.registerClass(UICollectionViewCell.self, forCellWithReuseIdentifier: "myCell")
          
          	self.view.addSubview(myCollectionView)
      
      	// UICollectionView 协议方法
      
          	// 设置行数
          	func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
              
              	return dataArray.count
          	}
          
          	// 设置网格显示的内容
          	func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
              
              	// 创建 cell
              	let cell = collectionView.dequeueReusableCellWithReuseIdentifier("myCell", forIndexPath: indexPath)
              
              	// 创建自定义 cell 视图
              
              	let imageView = UIImageView(frame: cell.bounds)
              	imageView.image = UIImage(named: dataArray[indexPath.item]["pic"]!)
              	cell.addSubview(imageView)
              
              	let label = UILabel(frame:CGRectMake(0, 5, cell.bounds.size.width, 20))
              	label.text = dataArray[indexPath.item]["name"]
              	label.textAlignment = NSTextAlignment.Center
              	cell.addSubview(label)
              
              	return cell
          	}
      

8、UICollectionView 协议方法

  • 需遵守协议 UICollectionViewDataSource, UICollectionViewDelegate,并设置代理

  • Objective-C

    • 分段、网格 设置

      	// 设置分段数
      	- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
      
          	return 3;
      	}
      
      	// 设置网格数
      	- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
      
          	return 15;
      	}
      
      	// 设置网格大小
      	- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
      
          	return CGSizeMake(100, 170);
      	}
      
      	// 设置每个网格的内容
      	- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
          
          	/*
              	cell 必须采用注册的方式自定义
           	*/
      
          	return cell;
      	}
      
    • 网格间距设置

      	// 设置最小网格间距
      	- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section {
      
          	/*
              	垂直滑动时,系统会根据屏幕宽度和网格(cell)的宽度在大于等于最小网格(cell)间距的范围内自动调整。
              	水平滑动时,系统会根据屏幕高度和网格(cell)的高度在大于等于最小网格(cell)间距的范围内自动调整。
           	*/
      
          	return 10;
      	}
      
      	// 设置最小行间距
      	- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section {
      
          	return 10;
      	}
      
      	// 设置分段周边距
      	- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
      
          	// 上,左,下,右
          	return UIEdgeInsetsMake(20, 10, 20, 10);
      	}
      
    • 分段头尾 设置

      	// 设置分段头大小
      	- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section {
      
          	/*
              	width 为水平滑动时的间距有效,height 为垂直滑动时的间距有效
           	*/
      
          	return CGSizeMake(20, 30);
      	}
      
      	// 设置分段尾大小
      	- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section {
      
          	/*
              	width 为水平滑动时的间距有效,height 为垂直滑动时的间距有效
           	*/
      
          	return CGSizeMake(20, 30);
      	}
      
      	// 设置分段头尾视图
      	- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath {
      
          	return myView;
      	}
      
    • 网格点击 设置

      	// 网格点击
      	- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
      
      	}
      
      	// 网格取消点击,点击另一个表格的时候触发
      	- (void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath {
      
      	}
      
  • Swift

    • 分段、网格 设置

      	// 设置分段数
      	func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
      
          	return 3
      	}
      
      	// 设置网格数
      	func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
      
          	return 15
      	}
      
      	// 设置网格大小
      	func collectionView(collectionView: UICollectionView!, layout collectionViewLayout: UICollectionViewLayout!, sizeForItemAtIndexPath indexPath: NSIndexPath!) -> CGSize {
      
          	return CGSizeMake(100, 170)
      	}
      
      	// 设置每个网格的内容
      	func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
      
          	/*
              	cell 必须采用注册的方式自定义
          	*/
      
          	return cell
      	}
      
    • 网格间距 设置

      	// 设置最小网格间距
      	func collectionView(collectionView: UICollectionView!, layout collectionViewLayout: UICollectionViewLayout!, minimumInteritemSpacingForSectionAtIndex:section) -> CGFloat {
      
          	/*
              	垂直滑动时,系统会根据屏幕宽度和网格(cell)的宽度在大于等于最小网格(cell)间距的范围内自动调整。
              	水平滑动时,系统会根据屏幕高度和网格(cell)的高度在大于等于最小网格(cell)间距的范围内自动调整。
           	*/
      
          	return 10
      	}
      
      	// 设置最小行间距
      	func collectionView(collectionView: UICollectionView!, layout collectionViewLayout: UICollectionViewLayout!, minimumLineSpacingForSectionAtIndex:section) -> CGFloat {
      
          	return 50
      	}
      
      	// 设置分段周边距
      	func collectionView(collectionView: UICollectionView!, layout collectionViewLayout: UICollectionViewLayout!, insetForSectionAtIndex:section) -> UIEdgeInsets {
      
          	// 上,左,下,右
          	return UIEdgeInsetsMake(20, 20, 20, 20)
      	}
      
    • 分段头尾 设置

      	// 设置分段头大小
      	func collectionView(collectionView: UICollectionView!, layut collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection:section) -> CGSize {
      
          	/*
              	width 为水平滑动时的间距有效,height 为垂直滑动时的间距有效
           	*/
      
          	return CGSizeMake(20, 30)
      	}
      
      	// 设置分段尾大小
      	func collectionView(collectionView: UICollectionView!, layut collectionViewLayout: UICollectionViewLayout, referenceSizeForFooterInSection:section) -> CGSize {
      
          	/*
              	width 为水平滑动时的间距有效,height 为垂直滑动时的间距有效
           	*/
      
          	return CGSizeMake(20, 30)
      	}
      
      	// 设置分段头尾视图
      	func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView {
      
          	return myView
      	}
      
    • 网格点击 设置

      	// 网格点击
      	func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
      
      	}
      
      	// 网格取消点击,点击另一个表格的时候触发
      	func collectionView(collectionView: UICollectionView, didDeselectItemAtIndexPath indexPath: NSIndexPath) {
      
      	}
      

9、Storyboard 中设置

  • 在 Storyboard 场景中设置

    • Collection View Controller

      CollectionView3

      Selection ...
      Clear on Appearance
    • Collection View

      CollectionView4

      Items 设置不同类型的单元格数量
      Layout 设置布局类型
      Scroll Direction 设置网格滑动方向
      Accessories
        Section Header  	|  显示网格头
        Section Footer  	|  显示网格尾
      

      CollectionView5

      Cell Size 网格单元的大小
      Header Size 网格头的大小
      Footer Size 网格尾的大小
      Min Spacing 最小行列间距
      Section Insets 网格边距
    • Collection Reusable View

      CollectionView6

      ntifier collectionViewCell 的 ID
  • 在 Storyboard 场景绑定的 Controller 中设置

    • 在 Storyboard 自带的 collectionViewCell 中没有 contentView,在使用 Cell 时显示的内容必须使用代码自定义,其它设置可以在系统自带的 Cell 上设置。
原文地址:https://www.cnblogs.com/QianChia/p/5758055.html