<ViewController.h>
#import <UIKit/UIKit.h> //遵守 UICollectionView 的两个协议 @interface ViewController : UIViewController <UICollectionViewDataSource,UICollectionViewDelegate,UICollectionViewDelegateFlowLayout> @end
<ViewController.m>
#import "ViewController.h" #import "MyCell.h" #import "Model.h" #import "UIImageView+WebCache.h" #define kCellIdentifier @"cell" #define kReusableViewHeader @"reusableViewHeader" #define kReusableViewFooter @"reusableViewFooter" @interface ViewController () @property (nonatomic,retain)NSMutableArray *dataArray;//用来存放从 bundle 读取的数据 @end UICollectionView *collectionView; @implementation ViewController -(void)dealloc { [_dataArray release]; [super dealloc]; } - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. //获取数据 [self getBundleData]; UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc]init]; //初始化 UICollectionView时,必须给定一个 layout, 否则程序会崩溃 collectionView = [[UICollectionView alloc]initWithFrame:self.view.bounds collectionViewLayout:flowLayout]; collectionView.backgroundColor = [UIColor whiteColor]; //设置代理 collectionView.delegate = self; collectionView.dataSource = self; //注册 item // [collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:kCellIdentifier]; //注册自定义 item [collectionView registerClass:[MyCell class] forCellWithReuseIdentifier:kCellIdentifier]; //注册header [collectionView registerClass:[UICollectionReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:kReusableViewHeader]; //注册 footer [collectionView registerClass:[UICollectionReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:kReusableViewFooter]; //flowlayout 的属性 //设置 section 的 header 的尺寸 flowLayout.headerReferenceSize = CGSizeMake(100, 80); //设置 section 的 footer 的尺寸 flowLayout.footerReferenceSize = CGSizeMake(40, 50); //设置 item 的尺寸 flowLayout.itemSize = CGSizeMake(80,100); //设置 item 的最小行间距 (纵向滑动时为行间距,横向滑动时为列间距)实际间距会均等分布 flowLayout.minimumLineSpacing = 30; //设置 item 的最小列间距 (纵向滑动时为列间距,横向滑动时为行间距) flowLayout.minimumInteritemSpacing = 10; //设置可以滚动方向(横向或者纵向,默认纵向滚动) // flowLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal; //设置section 的内延, 距离上左下右屏幕边缘的距离 flowLayout.sectionInset = UIEdgeInsetsMake(80, 80, 80, 80); [self.view addSubview:collectionView]; [collectionView release]; [flowLayout release]; } -(void)getBundleData { //数据解析 NSString *filePath = [[NSBundle mainBundle]pathForResource:@"Data" ofType:@"json"]; NSData *data = [NSData dataWithContentsOfFile:filePath]; NSError *error = nil; NSMutableArray *dataArray = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error]; if (error) { NSLog(@"error = %@",error); } //数据封装进对象 for (NSDictionary *dic in dataArray) { Model *model = [[Model alloc]init]; [model setValuesForKeysWithDictionary:dic]; [self.dataArray addObject:model]; } } // lazy loading -(NSMutableArray *)dataArray { if (!_dataArray) { _dataArray = [[[NSMutableArray alloc]init]autorelease]; } return [_dataArray retain]; } #pragma mark -- UICollectionViewDataSource //每个 section 中 Item 的数量 -(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { // if (section == 0) { // return 10; // }else if (section == 1){ // return 20; // }else { // return 30; // } return [_dataArray count]; } //section 的数量,默认返回为1 -(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView { return 3; } //设置 item -(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { // UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:kCellIdentifier forIndexPath:indexPath]; //自定义 tiem MyCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:kCellIdentifier forIndexPath:indexPath]; Model *model = [_dataArray objectAtIndex:indexPath.row]; //通过第三方为 cell 的 image 赋图片 [cell.imageView sd_setImageWithURL:[NSURL URLWithString:model.thumbURL]]; [cell.textLabel setText:[NSString stringWithFormat:@"S:%ld, R:%ld",indexPath.section,indexPath.row]]; [cell setBackgroundColor:[UIColor greenColor]]; return cell ; } //设置 section 的 header 和 footer的View,设置了header或者footer的size后才会触发此方法 -(UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath { //通过 kind 判断传入的是 header 或者 footer if ([kind isEqualToString:UICollectionElementKindSectionHeader]) { UICollectionReusableView *reusableView = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:kReusableViewHeader forIndexPath:indexPath]; [reusableView setBackgroundColor:[UIColor redColor]]; return reusableView; }else{ UICollectionReusableView *reusableView = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:kReusableViewFooter forIndexPath:indexPath]; [reusableView setBackgroundColor:[UIColor yellowColor]]; return reusableView; } } #pragma mark -- UICollectionViewDelegateFlowLayout -(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath { if (1 == indexPath.section) { return CGSizeMake(100, 100); } return CGSizeMake(50, 50); } //一般的, cell 根据大小不同注册多种标识的 cell 这样就不用通过此方法来修改 cell 大小了, 也不需要在重用时去重新布局 cell了.因为不同大小的同一个重用机制的 cell 在重用时会重用其frame, 所以需要重新布局,例如 MyCell 类中的 layoutSubviews 的方法 /* 进行 section 和 item 的插入删除 移动等编辑,自带动画效果 - (void)insertSections:(NSIndexSet *)sections; - (void)deleteSections:(NSIndexSet *)sections; - (void)reloadSections:(NSIndexSet *)sections; - (void)moveSection:(NSInteger)section toSection:(NSInteger)newSection; - (void)insertItemsAtIndexPaths:(NSArray *)indexPaths; - (void)deleteItemsAtIndexPaths:(NSArray *)indexPaths; - (void)reloadItemsAtIndexPaths:(NSArray *)indexPaths; - (void)moveItemAtIndexPath:(NSIndexPath *)indexPath toIndexPath:(NSIndexPath *)newIndexPath; */ - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end<Model.h>
#import <Foundation/Foundation.h> @interface Model : NSObject @property (nonatomic,copy)NSString *thumbURL; @property (nonatomic,copy)NSString *width; @property (nonatomic,copy)NSString *height; @end<Model.m>
#import "Model.h" @implementation Model -(void)dealloc { [_thumbURL release]; [_width release]; [_height release]; [super dealloc]; } @end<MyCell.h>
#import <UIKit/UIKit.h> @interface MyCell : UICollectionViewCell //用于图片显示 @property (nonatomic,retain)UIImageView *imageView; //用于文本显示 @property (nonatomic,retain)UILabel *textLabel; @end<MyCell.m>
#import "MyCell.h" @implementation MyCell -(void)dealloc { [_imageView release]; [_textLabel release]; [super dealloc]; } //初始化方法 -(id)initWithFrame:(CGRect)frame { if ([super initWithFrame:frame]) { [self addAllViews]; } return self; } //用来添加子视图 -(void)addAllViews { [self addSubview:self.imageView]; [self addSubview:self.textLabel]; } //懒加载 lazy loading //如果在调用 getter 方法时,如果不存在,那么就会创建一个 -(UIImageView *)imageView { if (!_imageView) { _imageView = [[[UIImageView alloc]initWithFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height * 3 / 4)]autorelease]; [_imageView setBackgroundColor:[UIColor lightGrayColor]]; } return _imageView; } -(UILabel *)textLabel { if (!_textLabel ) { _textLabel = [[[UILabel alloc]initWithFrame:CGRectMake(0, self.frame.size.height *3 / 4, self.frame.size.width, self.frame.size.height / 4)]autorelease]; [_textLabel setBackgroundColor:[UIColor brownColor]]; } return _textLabel; //注:当控件的frame 直接等于自身的 frame 时,布局就会混乱,一般需要微调一下 } //当自己的 frame 发生改变的时候,该方法就会被调用,用来重新布局子视图的位置 -(void)layoutSubviews { //调用父类方法 [super layoutSubviews]; [self.imageView setFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height * 3 / 4)]; [self.textLabel setFrame:CGRectMake(0, self.frame.size.height *3 / 4, self.frame.size.width, self.frame.size.height / 4)]; } @end