1、创建与基础设置
// 创建网格视图布局对象,可以设置滑动方向,cell 的间距等
UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
// 两个cell之间最小的行间距
flowLayout.minimumLineSpacing = 0;
// 两个cell之间最小的间距
flowLayout.minimumInteritemSpacing = 0;
// cell的滚动排布方向
flowLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
// 创建网格视图对象,必须带上布局对象
UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:flowLayout];
// 添加到父控件
[self.view addSubview:collectionView];
// 设置数据源
collectionView.dataSource = self;
// 设置代理
collectionView.delegate = self;
// 设置位置尺寸
collectionView.frame = self.view.bounse;
// 设置网格背景颜色
collectionView.backgroundColor = [UIColor clearColor];

// UICollectionView继承于UIScrollView,可使用父类设置属性
// 开启分页效果
collectionView.pagingEnabled = YES;
// 关闭弹簧效果
collectionView.bounces = NO;
// 不要显示水平滚动条
collectionView.showsHorizontalScrollIndicator = NO;

// 注册自定义表格视图
[collectionView registerClass:[CustomCollectionCell class] forCellWithReuseIdentifier:CustomCollectionCellID];
2、设置数据源与代理方法
// 设置分段数
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
    return 3;
}

// 设置网格数
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    return self.myDataArray.count;
}

// 设置网格大小
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)
indexPath {

    return CGSizeMake((self.view.bounds.size.width - 40) / 3, 150);
}

// 设置每个网格的内容
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {

    // 使用自定义 Cell 创建,cell 必须用注册的方式定义
    CustomCollectionCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:CustomCollectionCellID forIndexPath:indexPath];
    // 数据模型
	CustomItem *dataItem = self.myDataArray[indexPath.row];
    // 设置 Cell 数据模型
    cell.dataItem = dataItem;

    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);
}

// 网格点击
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {

}

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

}
3、自定义cell
  • 3.1 CustomCollectionCell.h

@class CustomItem;
@interface CustomCollectionCell : UICollectionViewCell

@property(nonatomic, strong) CustomItem *dataItem;

@end
  • 3.2 CustomCollectionCell.m

@interface CustomCollectionCell ()

@end

@implementation CustomCollectionCell

- (instancetype)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        // 添加子控件
    }
    return self;
}

// 设置数据
- (void)setDataItem:(CustomItem *)dataItem {
    _dataItem = dataItem;
    
}

// 布局子控件位置
- (void)layoutSubviews {
    [super layoutSubviews];
     
}

@end
4、自定义分段头尾的创建与引用
  • 4.1 引用

    // 注册分段头视图
    [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;
    }
    
  • 4.2 创建

    • 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;
    }
    
5、自定义布局风格
  • 5.1 CustomLayout.h

@interface CustomLayout : UICollectionViewLayout
  • 5.2 CustomLayout.m

@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;
}
  • 5.3 使用

CustomLayout *layout = [[CustomLayout alloc] init];
UICollectionView *myCollectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 20, self.view.bounds.size.width, self.view.bounds.size.height - 20) collectionViewLayout:layout];


作者: CH520