1.创建一个集合视图, 先创建网格布局 UICollectionViewFlowLayout, 设置其诸多属性
再用其设置好属性的对象 初始化集合视图.
- (void)createCollectView
{
// UICollectionViewFlowLayout 继承自 UICollectionViewLayout
// UICollectionViewLayout 是一个抽象类,该类没有具体功能, 具体的功能是由其子类(UICollectionViewFlowLayout)实现
// Item 布局 (网格状布局)
UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
// 行边距(相对于垂直滚动) <如果水平滑动行边距就是列边距>
flowLayout.minimumLineSpacing = 30;
// 列边距(相对于垂直滚动) <如果水平滑动行边距就是列边距>
flowLayout.minimumInteritemSpacing = 30;
// 设置item的宽高 (就是显示在上面的一小格子)
flowLayout.itemSize = CGSizeMake(80, 100); // 自动布局
// 设置滑动方向(默认是上下滑动的), 属性是枚举
flowLayout.scrollDirection = UICollectionViewScrollDirectionVertical;
//设置表头, 只有高度影响 (宽度默认是屏幕的宽)
flowLayout.headerReferenceSize = CGSizeMake(0, 100);
//NSLog(@"%d", index(<#const char *#>, <#int#>))
// 设置表尾
flowLayout.footerReferenceSize = CGSizeMake(50, 100);
// 设置内边距 上 左 下 右 !!!!!!!!!!!! 跟构建CGrectMake()差不多
flowLayout.sectionInset = UIEdgeInsetsMake(20, 20, 20, 20);
// 用设置好的flowLayout初始化集合视图
UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:[UIScreen mainScreen].bounds collectionViewLayout:flowLayout];
// 设置代理
collectionView.delegate = self;
collectionView.dataSource = self;
// collectionView 默认黑色, 现在改成白色
collectionView.backgroundColor = [UIColor whiteColor];
// 加到view上
[self.view addSubview:collectionView];
[collectionView release];
[flowLayout release];
//⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️
//⚡️⚡️⚡️⚡️注册你要用的cell⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️
// Identifier:@"MyCell" 重用标识符 一定要 上下一致(这里要和返回cell方法里面的标识符一致)
// <#(Class)#> 你的cell是那个类 就填那个类
// 使用系统的类就注册系统的 如果自定义cell就注册自定义的那个类
[collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"MyCell"];
//⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️
// 注册表头
// 注意 Identifier:@"MyHeaderView" 和复用里面一致
[collectionView registerClass:[UICollectionReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"MyHeaderView"]; //
//⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️⚡️
// 注册表尾
[collectionView registerClass:[UICollectionReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:@"MyFootView"];
}
2. 实现代理方法
//--------------- dataSouce 代理方法 开始 -------------------------
#pragma mark - dataSouce必须实现的代理方法 1 (两个)
// 必须实现的两个方法跟tableView一样
// 返回每个分区的Item 个数
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return 20;
}
#pragma mark - dataSouce必须实现的代理方法 2 (两个)
// 返回cell的样式
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
// 返回每个item的方法
// 这个方法包括了之前 创建tableViewCell写的一堆
// 必须有一步; 必须要注册cell⚡️⚡️
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"MyCell" forIndexPath:indexPath];
// cell点不出来 textLabel
// 系统没有像tableView一样, 给咱们提供布局方式, 咱们要使用UICollectionCiewCell的话, 一般都是自定义cell, 然后加到contentView上面
cell.contentView.backgroundColor = [UIColor colorWithRed:0.817 green:0.000 blue:0.823 alpha:1.000];
return cell; // 不需要释放
}
// 返回分区数, 跟tableView一样. 默认1个分区
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
return 1;
}
//设置表头 表尾的视图 通过代理方法来实现, 需要注册表头表位 (Reusable可重复的),
/**
* 设置表头 表尾 通过代理方法来实现 Reusable可重复的
* @param kind 这个参数可以判断是表头还是表尾 因为参数是字符串的不能用等号
* @param indexPath 索引
*/
// 此方法也是复用
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
{
// 判断返回 表头还是表尾
// (NSString *)kind ,这个参数可以判断是表头还是表尾, 因为参数是字符串的不能用等号
//
if ([kind isEqualToString:UICollectionElementKindSectionHeader]) {
// 返回表头, 需要去复用集合中得到
UICollectionReusableView *headView = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"MyHeaderView" forIndexPath:indexPath];
// 加颜色
headView.backgroundColor = [UIColor greenColor];
return headView;
} else {
// 返回表尾
UICollectionReusableView *footView =[collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:@"MyFootView" forIndexPath:indexPath];
footView.backgroundColor = [UIColor blueColor];
return footView;
}
}
开始自定义cell
1. 首先创建一个GirlCell类 : 继承自 UICollectionViewCell, 声明属性, 达到的目的: item上面放图片
#import <UIKit/UIKit.h>
#import "GirlModel.h"
@interface GirlCell : UICollectionViewCell
// 图片
@property (nonatomic, retain) UIImageView *girlImageView;
// 声明一个model获取宽高
@property (nonatomic, retain) GirlModel *model;
@end
2. GirlCell.m中重写初始化方法, 在初始化方法中创建控件, 并把控件加到self.contentView上(跟tableView的自定义cell类似)
// 重写初始化方法
// frame 这个参数 就是cell的frame
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// // 获取frame宽高
// CGFloat width = self.frame.size.width;
// CGFloat height = self.frame.size.height;
//
// // 跟 cell 一般大
// self.girlImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, width, height)];
//
// self.girlImageView.backgroundColor = [UIColor colorWithRed:0.867 green:0.000 blue:0.874 alpha:1.000];
//
// // 添加到显示视图上
// [self.contentView addSubview:self.girlImageView];
// [_girlImageView release];
// 动态imageView高度
self.girlImageView = [[UIImageView alloc] initWithFrame:CGRectZero];
[self.contentView addSubview:self.girlImageView];
[_girlImageView release];
}
return self;
}
#pragma mark - 重写方法 进行重新布局视图
- (void)layoutSubviews
{
[super layoutSubviews];
// 重新给imageView一个宽高
CGFloat scale = self.model.width / 150; // 这个150 是itemSize的高度
CGFloat newHeight = self.model.height / scale;
// 重新给图片的frame赋值
self.girlImageView.frame = CGRectMake(0, 0, 150, newHeight);
}
自定义表头视图(创建一个类继承自UICollectionReusableView)
#import <UIKit/UIKit.h>
@interface HeaderCollectionReusableView : UICollectionReusableView
// 声明label 用作表头显示的文字
@property (nonatomic, retain) UILabel *titleLabel;
@end
#import "HeaderCollectionReusableView.h"
@implementation HeaderCollectionReusableView
.m文件
- (void)dealloc
{
[_titleLabel release];
[super dealloc];
}
/**
自定义表头视图
*/
// 重写初始化方法
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// 初始化自定义视图
self.titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 0, 340, 50)];
self.titleLabel.backgroundColor = [UIColor yellowColor];
// 显示视图
[self addSubview:self.titleLabel];
[_titleLabel release];
}
return self;
}
@end
表尾视图(创建一个类继承自UICollectionReusableView)
#import <UIKit/UIKit.h>
@interface FooterCollectionReusableView : UICollectionReusableView
@property (nonatomic, retain) UIImageView *footerImageV;
@end
#import "FooterCollectionReusableView.h"
@implementation FooterCollectionReusableView
- (void)dealloc
{
[_footerImageV release];
[super dealloc];
}
/**
自定义表尾视图
*/
// 初始化控件
- (instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
// 初始化控件
self.footerImageV = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 370, 100)];
self.footerImageV.backgroundColor = [UIColor colorWithRed:0.500 green:0.285 blue:0.074 alpha:1.000];
[self addSubview:self.footerImageV];
[_footerImageV release];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(20 , 0, 180, 100)];
label.text = @"这是表尾";
label.font = [UIFont systemFontOfSize:24];
label.textColor = [UIColor redColor];
[self.footerImageV addSubview:label];
[label release];
}
return self;
}
-----------使用---------------
——把系统的改成自己创建的类------
------------------------------
//
// RootViewController.m
// LessonUICollectionView-GirlImage
//
// Created by lanou3g on 15/9/21.
// Copyright (c) 2015年 nieyinlong. All rights reserved.
//
#import "RootViewController.h"
#import "GirlModel.h"
#import "GirlCell.h"
#import "HeaderCollectionReusableView.h"
#import "FooterCollectionReusableView.h"
#import "DetailViewController.h"
#import "UIImageView+WebCache.h" // 导入第三方的类目
@interface RootViewController ()<UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout>
// 声明可变数组 保存model
@property (nonatomic, retain) NSMutableArray *dataArray;
@end
@implementation RootViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.navigationItem.title = @"自定义CollectionViewCell";
[self setUpData];
[self createCollectionView];
}
// 加载数据
- (void)setUpData
{
// 路径
NSString *path = [[NSBundle mainBundle] pathForResource:@"imageResource" ofType:@"json"];
NSData *data = [NSData dataWithContentsOfFile:path];
NSArray *array = [NSJSONSerialization JSONObjectWithData:data options:(NSJSONReadingMutableContainers) error:nil];
self.dataArray = [NSMutableArray array];
for (NSDictionary *dic in array) {
GirlModel *model = [[GirlModel alloc] init];
[model setValuesForKeysWithDictionary:dic];
[self.dataArray addObject:model];
[model release];
/**
*/
}
NSLog(@"%@", self.dataArray);
}
创建集合视图
- (void)createCollectionView
{
// 创建网状布局
UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
// 设置一堆属性
// 行间距
flowLayout.minimumLineSpacing = 20;
// 列间距
flowLayout.minimumInteritemSpacing = 20;
// item宽高
flowLayout.itemSize = CGSizeMake(150, 230);
// 滑动方向
flowLayout.scrollDirection = UICollectionViewScrollDirectionVertical;
// 头
flowLayout.headerReferenceSize = CGSizeMake(100, 100);
// 尾
flowLayout.footerReferenceSize = CGSizeMake(0, 200);
// 内边距 (上 左 下 右)
flowLayout.sectionInset = UIEdgeInsetsMake(20, 20, 20, 20);
/*----- 创建集合视图 --- --------------------*/
// 利用flowLayout 创建集合视图
UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:[UIScreen mainScreen].bounds collectionViewLayout:flowLayout];
// 设置代理
collectionView.delegate = self;
collectionView.dataSource = self;
collectionView.backgroundColor = [UIColor whiteColor];
// 显示视图
[self.view addSubview:collectionView];
// 释放 两个
[flowLayout release];
[collectionView release];
// 注册cell
// 改成自己的类
// 注意要注册的标示符 和下面的 返回cell方法里面的cell的标识符一致
[collectionView registerClass:[GirlCell class] forCellWithReuseIdentifier:@"GirlCell"];
// 注册表头 视图 (改成自己的类)
[collectionView registerClass:[HeaderCollectionReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"GirlHeader"];
// 注册表尾视图
[collectionView registerClass:[FooterCollectionReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:@"GirlFooter"];
}
#pragma mark ----- dataSouece 代理方法 ---
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return self.dataArray.count;
}
#pragma mark - 返回cell
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
GirlCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"GirlCell" forIndexPath:indexPath];
// 取出cell对于的model
GirlModel *model = self.dataArray[indexPath.row];
// 调用第三方类库 (实现异步加载图片)
[cell.girlImageView sd_setImageWithURL:[NSURL URLWithString:model.thumbURL] placeholderImage:[UIImage imageNamed:@"picholder@2x"]];
// 把model传进cell中 (那边实现自动布局)
cell.model = model;
return cell;
}
// 返回表头 表尾 的视图
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
{
// 判断返回 头还是返回脚
if ([kind isEqualToString:UICollectionElementKindSectionHeader]) {
// 从集合队列找, 没有就创建...
HeaderCollectionReusableView *headerView = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"GirlHeader" forIndexPath:indexPath];
headerView.titleLabel.text = @"这是表头的标题";
return headerView;
} else {
// 表尾视图
FooterCollectionReusableView *footView = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:@"GirlFooter" forIndexPath:indexPath];
footView.footerImageV.image = [UIImage imageNamed:@"22"];
return footView;
}
}
#pragma mark - 动态高度等比缩放
// 返回索引处 item的宽高
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout si zeForItemAtIndexPath:(NSIndexPath *)indexPath
{
// 取出对应的model(按索引取出model)
GirlModel *model = self.dataArray[indexPath.row];
// 算出图片刻度(或者比例)
CGFloat scale = model.width / 150; // 这个150 是item的宽
CGFloat newHeight = model.height / scale;
return CGSizeMake(150, newHeight);
}
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
DetailViewController *detVC = [[DetailViewController alloc] init];
detVC.model = self.dataArray[indexPath.row];
[self.navigationController pushViewController:detVC animated:YES];
[detVC release];
}
@end
异步加载图片 创建的model
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@interface GirlModel : NSObject
// 图片网址
@property (nonatomic, retain) NSString *thumbURL;
// 宽
@property (nonatomic, assign) CGFloat width;
// 高
@property (nonatomic, assign) CGFloat height;
/*
接口格式 数组里面存的好多小字典
"thumbURL": "http://img.tupianzj.com/uploads/allimg/140801/1-140P1104S7.jpg",
"width": 533,
"height": 796
*/
@end