UICollectionView

本文详细介绍了在iOS中使用UICollectionView实现九宫格数据展示的方法,包括UICollectionView的基本概念、如何设置数据源和布局、自定义布局的常用方法以及如何通过数据源方法展示数据。同时提供了纯代码示例,帮助开发者快速上手。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在iOS中,要实现九宫格数据展示,最常用的做法就是使用UICollectionView
UICollectionView继承自UIScrollView,因此支持垂直滚动或水平滚动,而且性能极佳


UICollectionView在iOS6中推出得,也是UIKit视图类中的一颗新星。它和UITableView共享API设计,但也在UITableView上做了一些扩展。UICollectionView最强大、同时显著超出UITableView的特色就是其完全灵活的布局结构

UITableView和UICollectionView都是由dataSoure和delegate驱动的。他们为其显示的子视图集扮演为愚蠢的容器,对他们真实的内容毫不知情。
**UICollectionViewFlowLayout简介
UICollectionView进一步抽象了。它将其子视图的位置,大小和外观的控制权委托给一个单独的布局对象。通过提供一个自定义布局对象,你几乎可以实现任何你能想象到的布局。布局继承自UICollectionViewLayout这个抽象基类。iOS6中以UICollectionViewFlowLayout类的形式提出了一个具体的布局实现。

flow layout可以被用来实现一个标准的grid view,这可能是在collection view中最常见的使用案例了。尽管大多数人都这么想,但是Apple很聪明,没有明确的命名这个类为UICollectionViewGridLayout。而使用了更为通用的术语flow layout,这更好的描述了该类的能力:它通过一个接一个的放置cell来建立自己的布局,当需要的时候,插入横排或竖排的分栏符。通过自定义滚动方向,大小和cell之间的间距,flow layout也可以在单行或单列中布局cell。


**如何展示数据

UICollectionView需要layout和数据源(dataSource) 来显示数据,

UICollecitonView会向数据源查询一共有多少行数据以及每一个显示什么数据等,在查询每一个显示什么数据前要确定设置了layout而且itemSize不能小于{0,0}

没有设置layout布局对象程序会崩溃
没有设置数据源和布局对象的UICollectionView只是个空壳

凡是遵守UITableViewDataSource协议的OC对象,都可以是UICollectionView的数据源

**UICollectionView常用数据源方法
调用数据源的下面方法得知一共有多少组数据
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView;

调用数据源的下面方法得知每一组有多少项数据
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section;

调用数据源的下面方法得知每一项显示什么内容
- (UICollectionViewCell *)collectionView:(UICollectionView *) collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath;

UICollectionView的数据源必须实现第二个方法和第三个方法,第一个方法不实现默认就是1组

**UICollectionView的常见属性
布局对象
@property (nonatomic, strong) UICollectionViewLayout *collectionViewLayout;

背景视图,会自动填充整个UICollectionView
@property (nonatomic, strong) UIView *backgroundView;

是否允许选中cell 默认允许选中
@property (nonatomic) BOOL allowsSelection;

是否可以多选 默认只是单选
@property (nonatomic) BOOL allowsMultipleSelection;
水平进度条:shows。。。

**UICollectionViewFlowLayout常用属性
cell之间的最小行间距                                     
@property (nonatomic) CGFloat minimumLineSpacing
cell之间的最小列间距                
 @property (nonatomic) CGFloat minimumInteritemSpacing;默认值为10;
  cell的尺寸  
@property (nonatomic) CGSize itemSize;
cell的预估尺寸 
@property (nonatomic) CGSize estimatedItemSize;
UICollectionView的滚动方向,默认是垂直滚动
@property (nonatomic) UICollectionViewScrollDirection scrollDirection;
HeaderView的尺寸  
  
@property (nonatomic) CGSize headerReferenceSize;

FooterView的尺寸  
  
@property (nonatomic) CGSize footerReferenceSize;

分区的四边距  
@property (nonatomic) UIEdgeInsets sectionInset;

设置是否当元素超出屏幕之后固定页眉视图位置,默认NO
  
 @property (nonatomic) BOOL sectionHeadersPinToVisibleBounds;

设置是否当元素超出屏幕之后固定页脚视图位置,默认NO  
  
 @property (nonatomic) BOOL sectionFootersPinToVisibleBounds

****自定义布局的常用方法
UICollectionView将要显示时准备布局,每当布局更新时,调用该方法做布局前的准备                                                                     - (void)prepareLayout;

创建指定索引的cell的布局属性                                
 
           
 - (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPat;

返回UICollectionView内所有的控件的布局属性                      

          
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect;

自定义布局时一定要实现此方法来返回UICollectionView的contentSize,内容尺寸,UICollectionView的滚动范围                                            
- (CGSize)collectionViewContentSize; 

纯代码方式使用CollectionView
#import "ViewController.h"

@interface ViewController () <UICollectionViewDataSource>

@end

@implementation ViewController


static NSString * const ID = @"test_cell";

#pragma mark - collection view data source

// 设置组的个数
- (
NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
   
return 7;
}

// 设置每组有多少个项(格子)
- (
NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
   
return section + 1;
}

// 返回每组的每行的cell
- (
UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
   
   
// 1. 创建Cell
   
   
// 创建一个Cell
   
// dequeueReusableCellWithReuseIdentifier: 方法, 首先从缓存池中查找是否有对应的cell, 如果有, 那么就返回;如果没有那么这个方法内部会帮我们创建一个cell。前提是我们需要告诉collectionview,我们要的cell的类型【将来要创建哪个类型的对象作为我们的cell
   
   
// 注册Cell 前提是我们需要告诉collectionview,我们要的cell的类型【将来要创建哪个类型的对象作为我们的cell
   
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:ID forIndexPath:indexPath];
   
    cell.
backgroundColor = [UIColor redColor];
   
   
// 2. 返回Cell
   
return cell;
}




#pragma mark - viewDidLoad
- (void)viewDidLoad {
    [
super viewDidLoad];
   
// 1. 创建一个UICollectionView控件
   
// 1.1 先创建一个布局对象
    UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];

//也可以这样获取布局
1 .获取flowlaytout(通过拖线获取布局);,修改item的大小
//    self.flowLayout.itemSize = CGSizeMake(100, 100);
2 .获取布局(通过代码获取)
     UICollectionViewFlowLayout *flowLayout =  (UICollectionViewFlowLayout *) self.collectionView.collectionViewLayout;
    // 设置每个Cell的大小
    flowLayout.
itemSize = CGSizeMake(60, 60);
   
   
// 设置组与组之间的间隔
    flowLayout.
sectionInset = UIEdgeInsetsMake(50, 10, 0, 10);
   
   
// 设置每个格子之间的最小水平间距
    flowLayout.
minimumInteritemSpacing = 2;
   
   
// 设置行间距(设置最小行间距)
    flowLayout.
minimumLineSpacing = 20;
   
   
   
// 1.2 创建一个collection view对象
   
UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:self.view.bounds collectionViewLayout:flowLayout];
   
   
   
// 设置背景色
    collectionView.
backgroundColor = [UIColor blueColor];
   
   
   
// collection view设置数据源对象
    collectionView.
dataSource = self;

   
    // 注册Cell:
    [collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:ID];
   
   
   
// 2. CollectionView添加到控制器的view
    [
self.view addSubview:collectionView];
   
   
}

- (
void)didReceiveMemoryWarning {
    [
super didReceiveMemoryWarning];
   
// Dispose of any resources that can be recreated.
}


//选定第一个为选中状态
               
NSIndexPath * indexPath = [ NSIndexPath indexPathForItem:0 inSection:0];
                
// 默认选中某一行的方法
                [ self selectItemAtIndexPath:indexPath animated:YES scrollPosition:UICollectionViewScrollPositionNone];

//
[collectionView scrollToItemAtIndexPath:indexpath atScrollPosition:UICollectionViewScrollPositionNone animated:YES];
@end

注意:自定义cell时。注册cell 之后,首先需要实例化cell,必须使用initWithFrame:方法;
属性:


 代理方法:
选中某行的方法
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
   
// 点击的时候,新闻主界面加载对应的新闻(滚动到对应的频道就会自动加载数据.)
    
//当选中某一行时,发出通知,
    [[
NSNotificationCenter defaultCenter] postNotificationName:@"newsData" object:indexPath];
   
   
//cell本身也滚动到中心位置
    [
self scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionCenteredVertically animated:YES];
   
//   获取模型数据
   
// 1. 取出这一行对应的数据
   
LZJNewsChannelModel * channel = self.channels[indexPath.item];
   
   
// 2. 重新赋值
   
// 2.1 取出这一行对应的 cell
   
LZJNewsChannelCell * cell =(LZJNewsChannelCell *)[collectionView cellForItemAtIndexPath:indexPath];
   
//重新赋值
    cell.
channel = channel;
   
}


已经选中某行的方法:
- (void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath{
   
   
//   获取模型数据
   
// 1. 取出这一行对应的数据
   
LZJNewsChannelModel * channel = self.channels[indexPath.item];
   
   
// 2. 重新赋值
   
// 2.1 取出这一行对应的 cell
   
LZJNewsChannelCell * cell =(LZJNewsChannelCell *)[collectionView cellForItemAtIndexPath:indexPath];
   
//重新赋值
    cell.
channel = channel;
   
 
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值