UICollectionView

在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;
   
 
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值