[iOS]UICollectionView布局使用

时间:2024-04-05 15:03:39

UICollectionView组件从iOS5开始就有了,但是一般项目很少用。这里还是梳理一下它的使用方法。

我们看到很多电商类APP,比如:天猫,京东,里面的商品列表,就可以用UICollectionView来实现。

借用苹果的一张图了解下它的工作流程:

[iOS]UICollectionView布局使用

 

a、首先我们从APP界面上看到的是一行行和一列列的单元格,就是类似tableview的cell.在UICollectionView里面叫UICollectionViewCell.

b、正如上面item a所述,UICollectionView是一个容器,它用来装载一个个cell

c、cell的呈现方式或者我们叫layout方式。一般而言简单的就是苹果跟我们提供好的UICollectionViewFlowLayout,直接用即可,更复杂的界面布局我们可以自定义

d、cell的数据源来自哪里以及对cell的操作是怎么样的,这里就是跟table类似了,通过dataSoure和delegate来实现。这一部分比较简单。

最关键的还是item c里面的描述,布局方式是重点。接下来我们看看下UICollectionViewFlowLayout。

//同一组当中,垂直方向:行与行之间的间距;水平方向:列与列之间的间距
@property (nonatomic) CGFloat minimumLineSpacing;
//垂直方向:同一行中的cell之间的间距;水平方向:同一列中,cell与cell之间的间距
@property (nonatomic) CGFloat minimumInteritemSpacing;
//每个cell统一尺寸
@property (nonatomic) CGSize itemSize;
//滑动反向,默认滑动方向是垂直方向滑动
@property (nonatomic) UICollectionViewScrollDirection scrollDirection;
//每一组头视图的尺寸。如果是垂直方向滑动,则只有高起作用;如果是水平方向滑动,则只有宽起作用。
@property (nonatomic) CGSize headerReferenceSize;
//每一组尾部视图的尺寸。如果是垂直方向滑动,则只有高起作用;如果是水平方向滑动,则只有宽起作用。
@property (nonatomic) CGSize footerReferenceSize;
//每一组的内容缩进
@property (nonatomic) UIEdgeInsets sectionInset;

里面有详细说明,使用方法一目了然。

这里有个地方注意:

a、section的概念:可以理解为章节。我们把UICollectionView想象成一个抽屉,抽屉有很多节,一节就是一个secion。节与节之间有间隔。

b、一个cell可以放几个item计算问题:

具体计算公式是: 
cellCount=(CollectionViewContentWidth-sectionInset.left-sectionInset.right+minimumInteritemSpacing)/(itemSize.width+minimumInteritemSpacing)

c、还有一个容易忽视的问题:section的头部视图和尾部视图大小,我们一般情况只会指定一个。比如头部视图:headerReferenceSize。设置它的大小就可以决定secion之间的间隔,就像刚才提到的抽屉之间的间隔。

 

这里也有一个简单使用demo:

1、通过xib自定义一个UICollectionViewCell。

这里只显示一个Button,居中

2、在viewcontroller里面使用。


#import "ViewController1.h"
#import "CollectionViewCell1.h"

@interface ViewController1 ()<UICollectionViewDataSource,UICollectionViewDelegate>
@property (nonatomic, strong) UICollectionView *collectView1;
@property (nonatomic, strong) NSMutableArray *dataArray1;
@property (nonatomic, strong) UICollectionViewFlowLayout *layout1;
@end

@implementation ViewController1

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    [self setupViews];
}

- (void)setupViews{
    self.view.backgroundColor = [UIColor whiteColor];
    [self.view addSubview:self.collectView1];
}

#pragma mark - Lazy load
- (UICollectionView *)collectView1{
    if (!_collectView1) {
        _collectView1 = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 0,self.view.bounds.size.width, self.view.bounds.size.height) collectionViewLayout:self.layout1];
        _collectView1.backgroundColor = [UIColor clearColor];
        _collectView1.delegate = self;
        _collectView1.dataSource = self;
        [_collectView1 registerNib:[UINib nibWithNibName:@"CollectionViewCell1" bundle:[NSBundle mainBundle]] forCellWithReuseIdentifier:@"CollectionViewCell1"];
    }
    
    return _collectView1;
}

- (UICollectionViewFlowLayout *)layout1 {
    if (!_layout1) {
        _layout1 = [UICollectionViewFlowLayout new];
        _layout1.minimumLineSpacing = 10;
        _layout1.minimumInteritemSpacing = 10;
        _layout1.itemSize = CGSizeMake((self.view.frame.size.width - 20)/3.0, 40);
        _layout1.headerReferenceSize = CGSizeMake(10, 40);
    }
    return _layout1;
}

- (NSMutableArray *)dataArray1 {
    if (!_dataArray1) {
        _dataArray1 = [NSMutableArray arrayWithObjects:@"1",@"2",@"3",@"4",@"5", nil];
    }
    
    return _dataArray1;
}

#pragma mark - UICollectionViewDataSource
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
    return 10;
}

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    return self.dataArray1.count;
}

- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    
    CollectionViewCell1 *cell1 = [collectionView dequeueReusableCellWithReuseIdentifier:@"CollectionViewCell1" forIndexPath:indexPath];
    cell1.backgroundColor = [UIColor lightGrayColor];
    NSString *title = self.dataArray1[indexPath.row];
    [cell1.testBtn setTitle:title forState:UIControlStateNormal];
    
    return cell1;
}

@end