UICollectionView详解和UITableView的区别

1. UICollectionView 和 UITableView 的UI区别

UICollectionView默认没有表头,  UITableView: 有表头和表尾;

UICollectionView的区里面是项Item,  UITableView:区里面是单元格Cell

UICollectionView布局使用UICollectionViewLayOut的子类(UICollectionViewFlowLayOut 流式布局:流式布局的特点就是会自动根据屏幕的宽度适当的显示列数,如果屏幕款显示的列数可能就多,例如iphone 6s Plus, 如果屏幕相对较窄,显示的列数则较少,例如 iphone 4s)

UICollectionView和UITableView都是分区(段)的

影响UICollectionView显示的列数的因素有: 

①:UICollectionView宽度,宽度越大,显示列数越多; 

②:Item宽度, 每一项的宽度越窄,则显示的列数越多; 

③: 每个Item的列间隙,列间距越窄,显示的越多;


影响UICollectionView 行数的因素:

 UICollectionView 的行数是不能显式指定的,行数是系统自动计算出来的,行数的计算因素有: Item 宽度 和 列间隙  共同决定


UICollectionView 滚动方向与Item的排列方向

滚动方向不同,每个Item的出现顺序也不同;

滚动方向如果是垂直方向,那么Item是横着排列,先排第一行,如果一行排列不完,就继续排第二行;

滚动方向如果是水平方向,那么Item是垂直排列,先排第一列,如果一列排列不完,就继续排序第二列,如果有多个分区,每个分区的第一项肯定再第一行,而不会排在排在上一个分区的尾部,而是另起一列

UICollectionViewScrollDirectionVertical(垂直方向) UICollectionViewScrollDirectionHorizontal (水平方向)

                                                                                     由图可见,滚动方向 垂直和水平 第二个Item出现的位置不同

滚动方向和排列方向 成垂直关系, 如下图解:



2.UICollectionView 知识点


UICollectionViewFlowLayout:Item 的流式布局

@interface UICollectionViewFlowLayout : UICollectionViewLayout

@property (nonatomic) CGFloat minimumLineSpacing;		     // 最小行间距
@property (nonatomic) CGFloat minimumInteritemSpacing;		     // 最小内间距(列间距)
@property (nonatomic) CGSize itemSize;				     // Item 的宽、高
@property (nonatomic) CGSize estimatedItemSize NS_AVAILABLE_IOS(8_0);
@property (nonatomic) UICollectionViewScrollDirection scrollDirection;// 滚动方向:垂直和水平
@property (nonatomic) CGSize headerReferenceSize;	// 段头的宽高
@property (nonatomic) CGSize footerReferenceSize;       // 段尾的宽高

@property (nonatomic) UIEdgeInsets sectionInset;        // 段的上下左右的内边距 padding(多个分区一般都会设置该值,如果不设置,多个区会连在一块)

@property (nonatomic) BOOL sectionHeadersPinToVisibleBounds NS_AVAILABLE_IOS(9_0);
@property (nonatomic) BOOL sectionFootersPinToVisibleBounds NS_AVAILABLE_IOS(9_0);

@end 

UICollectionView 

@interface UICollectionView : UIScrollView

- (void)registerClass:(nullable Class)cellClass forCellWithReuseIdentifier:(NSString *)identifier;

@end

UICollectionViewFlowLayout 的属性设置

流式布局的Item设置:
①:使用UICollectionViewFlowLayout的属性进行设置(此种方法是对所有Item都统一设置)
②:使用UICollectionViewDelegateFlowLayout协议进行设置(此种方法即可以统一设置又可以对某些Item进行特殊设置)

UICollectionViewDelegateFlowLayout 协议不是必须要实现的,可以通过属性来设置,例如
- (void)viewDidLoad {
    [super viewDidLoad];
    
    _dataSource = [NSArray arrayWithObjects:@"0", @"1", @"2", @"3", @"4", @"5", @"6", @"7", nil];
    
    UICollectionViewFlowLayout * layout = [[UICollectionViewFlowLayout alloc] init];
    layout.scrollDirection = UICollectionViewScrollDirectionVertical;
    layout.itemSize = CGSizeMake(96, 96);
    layout.minimumInteritemSpacing = 20.0;
    layout.minimumLineSpacing = 20.0;
    layout.headerReferenceSize = CGSizeMake(100.0, 50.0);// 指定section的头部高度
    layout.footerReferenceSize = CGSizeMake(100.0, 50.0);
    layout.sectionInset = UIEdgeInsetsMake(0, 10.0, 0, 10.0); // 段的内边距 padding(上下左右)
    UICollectionView * collectionView = [[UICollectionView alloc] initWithFrame:self.view.frame collectionViewLayout:layout];
    [collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"Cell"];
    collectionView.delegate = self;
    collectionView.dataSource = self;
    
    [self.view addSubview:collectionView];
}

或者在创建UICollectionViewDelegateFlowLayout的时候不设置itemSize,然后在协议中设置
#pragma mark -
#pragma mark - UICollectionViewDelegateFlowLayout
// 定义单元格的宽 高
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
    return CGSizeMake(96, 96);
}

// 定义 单元格之间的间距  top bottom right left margin
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
    return UIEdgeInsetsMake(10, 10, 10, 10);
}

Item的宽高

一般情况下每个Item的宽高是一致的,但也可以不一致(需要实现UICollectionViewDelegateFlowLayout协议来定制)

3. 示例代码

① 基础示例:

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController <UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout>

@property (nonatomic, retain) NSArray * dataSource;

@end
#import "ViewController.h"


@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.title = @"UICollectionView Demo";
    
    _dataSource = [NSArray arrayWithObjects:@"0", @"1", @"2", @"3", @"4", @"5", @"6", @"7", nil];
    
    UICollectionViewFlowLayout * layout = [[UICollectionViewFlowLayout alloc] init];
    layout.scrollDirection = UICollectionViewScrollDirectionVertical;
    
    UICollectionView * collectionView = [[UICollectionView alloc] initWithFrame:self.view.frame collectionViewLayout:layout];
    [collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"Cell"];
    collectionView.delegate = self;
    collectionView.dataSource = self;
    
    [self.view addSubview:collectionView];
}

#pragma mark -
#pragma mark - UICollectionViewDataSource
// 共有几段
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
    return 1;
}

// 每段有多少项
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    return _dataSource.count;
}

// 单元格内容
- (UICollectionViewCell *) collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    static NSString * CellIdentifier = @"Cell";
    UICollectionViewCell * cell = [collectionView dequeueReusableCellWithReuseIdentifier:CellIdentifier forIndexPath:indexPath];
    cell.backgroundColor = [UIColor grayColor];
    
    UIView * contentView = [[UIView alloc] init];
    UILabel * label = [[UILabel alloc] initWithFrame:CGRectMake(20, 20, 50, 50)];
    label.text = _dataSource[indexPath.row];
    [contentView addSubview:label];
    
    cell.backgroundView = contentView;
    
    return cell;
}

#pragma mark -
#pragma mark - UICollectionViewDelegateFlowLayout
// 定义单元格的宽 高
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
    return CGSizeMake(96, 96);
}

// 定义 单元格之间的间距  top bottom right left margin
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
    return UIEdgeInsetsMake(10, 10, 10, 10);
}

#pragma mark -
#pragma mark - UICollectionView Deleage
// 能否选中单元格
- (BOOL)collectionView:(UICollectionView *)collectionView shouldSelectItemAtIndexPath:(NSIndexPath *)indexPath {
    return YES;
}

- (void) collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
    NSLog(@"row:%ld----------section: %ld", indexPath.row,  indexPath.section);
}

滚动方向:垂直, 分4区段,效果如下                            滚动方向:水平, 分3区段,效果如下


② 段头

- (void)viewDidLoad {
    [super viewDidLoad];
    _dataSource = [NSArray arrayWithObjects:@"0", @"1", @"2", @"3", @"4", @"5", @"6", @"7", nil];
    
    UICollectionViewFlowLayout * layout = [[UICollectionViewFlowLayout alloc] init];
    layout.scrollDirection = UICollectionViewScrollDirectionVertical;
    layout.sectionInset = UIEdgeInsetsMake(20, 20, 20, 20);
    layout.headerReferenceSize = CGSizeMake(300, 60);		// 设置段的宽高
    
    UICollectionView * collectionView = [[UICollectionView alloc] initWithFrame:self.view.frame collectionViewLayout:layout];
    [collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"Cell"];
    
    // 注册段头
    [collectionView registerClass:[UICollectionReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"ReusableView"];
    
    collectionView.delegate = self;
    collectionView.dataSource = self;
    
    [self.view addSubview:collectionView];
}


// 实现协议方法
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath {

    UICollectionReusableView * headerView = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader
                                                                               withReuseIdentifier:@"ReusableView"
                                                                                      forIndexPath:indexPath];
    UIView * contentView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 50)];
    contentView.backgroundColor = [UIColor grayColor];
    UILabel * label = [[UILabel alloc] initWithFrame:CGRectMake(20, 10, self.view.frame.size.width, 30)];
    label.text = [NSString stringWithFormat:@"Section Header: %ld", indexPath.section];
    label.textAlignment = NSTextAlignmentCenter;
    [contentView addSubview:label];
    
    
    [headerView addSubview:contentView];
    return headerView;
}

效果如图:



③ 自定义Cell

#import <UIKit/UIKit.h>

@interface CollectionViewCell : UICollectionViewCell

@property (nonatomic, retain) UIImageView * imageView;
@property (nonatomic, retain) UILabel * textLabel;

@end
#import "CollectionViewCell.h"

@implementation CollectionViewCell


- (id) initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        self.backgroundColor = [UIColor grayColor];
        
        CGFloat itemWidth = self.frame.size.width;
        CGFloat itemHeight = self.frame.size.height;
        
        _imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, itemWidth, itemHeight - 30)];
        [self addSubview:_imageView];
        
        _textLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, itemHeight - 20, itemWidth, 20)];
        _textLabel.textAlignment = NSTextAlignmentCenter;
        
        [self addSubview:_textLabel];
        
    }
    
    return self;
}

@end
- (void)viewDidLoad {
    [super viewDidLoad];
    self.title = @"UICollectionView Demo";
    
    UICollectionViewFlowLayout * layout = [[UICollectionViewFlowLayout alloc] init];
    layout.scrollDirection = UICollectionViewScrollDirectionVertical;
    layout.sectionInset = UIEdgeInsetsMake(20, 20, 20, 20);
    
    UICollectionView * collectionView = [[UICollectionView alloc] initWithFrame:self.view.frame collectionViewLayout:layout];
    [collectionView registerClass:[CollectionViewCell class] forCellWithReuseIdentifier:@"Cell"];	// 注册类型是自定义类型
    collectionView.delegate = self;
    collectionView.dataSource = self;
    
    [self.view addSubview:collectionView];
}

// 单元格内容
- (UICollectionViewCell *) collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    static NSString * CellIdentifier = @"Cell";
    CollectionViewCell * cell = [collectionView dequeueReusableCellWithReuseIdentifier:CellIdentifier forIndexPath:indexPath];
    cell.backgroundColor = [UIColor grayColor];
    
    // 给自定义的UI赋值
    cell.imageView.image = [UIImage imageNamed:@"cat"];
    cell.textLabel.text = @"闰土";
    
    return cell;
}

其他省略掉的代码和上个示例的完全一样,效果如图:



使用UICollectionView注意事项:
1. 初始化时必须指定布局
2.必须注册Cell
3. 一般要自定义cell

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风流 少年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值