前言
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

-
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

-
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
-
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
-
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
Selection ... Clear on Appearance -
Collection View
Items 设置不同类型的单元格数量 Layout 设置布局类型 Scroll Direction 设置网格滑动方向 Accessories Section Header | 显示网格头 Section Footer | 显示网格尾
Cell Size 网格单元的大小 Header Size 网格头的大小 Footer Size 网格尾的大小 Min Spacing 最小行列间距 Section Insets 网格边距 -
Collection Reusable View
ntifier collectionViewCell 的 ID
-
-
在 Storyboard 场景绑定的 Controller 中设置
- 在 Storyboard 自带的 collectionViewCell 中没有 contentView,在使用 Cell 时显示的内容必须使用代码自定义,其它设置可以在系统自带的 Cell 上设置。