使用UICollectionView

简介:

使用UICollectionView

 

使用UICollectionView的流程:

1. 设定一个UICollectionViewFlowLayout

2. 使用这个设定的UICollectionViewFlowLayout来初始化UICollectionView

3. 设置代理对象

4. 继承UICollectionViewCell设定重用的cell

源码:

LargeUICollectionViewFlowLayout.h + LargeUICollectionViewFlowLayout.m

#import <UIKit/UIKit.h>

@interface LargeUICollectionViewFlowLayout : UICollectionViewFlowLayout

@end


#import "LargeUICollectionViewFlowLayout.h"

@implementation LargeUICollectionViewFlowLayout

- (instancetype)init
{
    self = [super init];
    if (self)
    {
        self.itemSize                = CGSizeMake(70, 70);
        self.sectionInset            = UIEdgeInsetsMake(0, 0, 0, 0);
        self.minimumInteritemSpacing = 40.0f;
        self.minimumLineSpacing      = 5.0f;
    }
    return self;
}

@end

ShowCollectionViewCell.h + ShowCollectionViewCell.m
#import <UIKit/UIKit.h>

@interface ShowCollectionViewCell : UICollectionViewCell

@end


#import "ShowCollectionViewCell.h"

@implementation ShowCollectionViewCell

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self)
    {
        self.backgroundColor = [UIColor redColor];
    }
    
    return self;
}

@end

RootViewController.h + RootViewController.m
#import <UIKit/UIKit.h>

@interface RootViewController : UIViewController

@end


#import "RootViewController.h"
#import "ShowCollectionViewCell.h"
#import "LargeUICollectionViewFlowLayout.h"

static NSString *identify = @"ItemIdentifier";

@interface RootViewController ()<UICollectionViewDelegate, UICollectionViewDataSource>

@property (nonatomic, strong) UICollectionView *collectionView;

@end

@implementation RootViewController


- (void)viewDidLoad
{
    [super viewDidLoad];

    // 初始化UICollectionView并指定一个UICollectionViewFlowLayout
    self.collectionView = \
    [[UICollectionView alloc] initWithFrame:self.view.bounds
                       collectionViewLayout:[LargeUICollectionViewFlowLayout new]];
    
    // 给UICollectionViewCell注册重用标示(collectionView会自动给我们创建重用的cell对象)
    [self.collectionView registerClass:[ShowCollectionViewCell class]
            forCellWithReuseIdentifier:@"ItemIdentifier"];
    
    // 设置代理对象
    self.collectionView.delegate   = self;
    self.collectionView.dataSource = self;
    
    // 将UICollectionView添加进父视图
    [self.view addSubview:_collectionView];
}

-(NSInteger)collectionView:(UICollectionView *)collectionView
    numberOfItemsInSection:(NSInteger)section
{
    return 100;
}

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
                 cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    ShowCollectionViewCell *cell = \
    [collectionView dequeueReusableCellWithReuseIdentifier:@"ItemIdentifier"
                                              forIndexPath:indexPath];
    
    return cell;
}

@end

运行后效果如下:

很重要的参数如下所示:

在ShowCollectionViewCell.m中执行打印操作:

打印信息如下:

2014-05-19 16:52:58.873 UICollectionView[3077:60b] {{0, 0}, {70, 70}}       A
2014-05-19 16:52:58.875 UICollectionView[3077:60b] {{125, 0}, {70, 70}}   B
2014-05-19 16:52:58.875 UICollectionView[3077:60b] {{250, 0}, {70, 70}}   C
2014-05-19 16:52:58.875 UICollectionView[3077:60b] {{0, 75}, {70, 70}}     D
2014-05-19 16:52:58.876 UICollectionView[3077:60b] {{125, 75}, {70, 70}}
2014-05-19 16:52:58.876 UICollectionView[3077:60b] {{250, 75}, {70, 70}}
2014-05-19 16:52:58.876 UICollectionView[3077:60b] {{0, 150}, {70, 70}}
2014-05-19 16:52:58.877 UICollectionView[3077:60b] {{125, 150}, {70, 70}}
2014-05-19 16:52:58.877 UICollectionView[3077:60b] {{250, 150}, {70, 70}}
2014-05-19 16:52:58.877 UICollectionView[3077:60b] {{0, 225}, {70, 70}}
2014-05-19 16:52:58.878 UICollectionView[3077:60b] {{125, 225}, {70, 70}}
2014-05-19 16:52:58.878 UICollectionView[3077:60b] {{250, 225}, {70, 70}}
2014-05-19 16:52:58.878 UICollectionView[3077:60b] {{0, 300}, {70, 70}}
2014-05-19 16:52:58.879 UICollectionView[3077:60b] {{125, 300}, {70, 70}}
2014-05-19 16:52:58.879 UICollectionView[3077:60b] {{250, 300}, {70, 70}}
2014-05-19 16:52:58.879 UICollectionView[3077:60b] {{0, 375}, {70, 70}}
2014-05-19 16:52:58.880 UICollectionView[3077:60b] {{125, 375}, {70, 70}}
2014-05-19 16:52:58.901 UICollectionView[3077:60b] {{250, 375}, {70, 70}}
2014-05-19 16:52:58.901 UICollectionView[3077:60b] {{0, 450}, {70, 70}}
2014-05-19 16:52:58.902 UICollectionView[3077:60b] {{125, 450}, {70, 70}}
2014-05-19 16:52:58.902 UICollectionView[3077:60b] {{250, 450}, {70, 70}}
2014-05-19 16:52:58.902 UICollectionView[3077:60b] {{0, 525}, {70, 70}}
2014-05-19 16:52:58.903 UICollectionView[3077:60b] {{125, 525}, {70, 70}}
2014-05-19 16:52:58.903 UICollectionView[3077:60b] {{250, 525}, {70, 70}}
2014-05-19 16:53:24.995 UICollectionView[3077:60b] {{0, 600}, {70, 70}}
2014-05-19 16:53:24.996 UICollectionView[3077:60b] {{125, 600}, {70, 70}}
2014-05-19 16:53:24.996 UICollectionView[3077:60b] {{250, 600}, {70, 70}}

分析上述打印信息A,B不难发现:125 - 70 = 55 > 40,所以,minimumInteritemSpacing只是单元格间的最小间距而已.

分析A,D发现,75 - 70 = 5,与minimumLineSpacing设定一致,因为我们是垂直滚动,所以纵向方向的间距是一致的.

 

 

知道这些,我们来实现网络请求照片墙的效果.

修改LargeUICollectionViewFlowLayout中的代码如下:

        self.itemSize                = CGSizeMake(100, 150);         // 单元格尺寸
        self.sectionInset            = UIEdgeInsetsMake(0, 0, 0, 0); // 单元格边缘
        self.minimumInteritemSpacing = 10.0f;                        // 横排单元格最小间隔
        self.minimumLineSpacing      = 10.0f;                        // 单元格最小行间距

修改ShowCollectionViewCell.h + ShowCollectionViewCell.m

#import <UIKit/UIKit.h>

@interface ShowCollectionViewCell : UICollectionViewCell

@property (nonatomic, strong) UIImageView  *showImageView;

@end


#import "ShowCollectionViewCell.h"

@implementation ShowCollectionViewCell

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self)
    {
        self.backgroundColor = [UIColor whiteColor];
        
        CGRect rect = self.bounds;
        rect.origin.x    += 3;
        rect.origin.y    += 3;
        rect.size.height -= 6;
        rect.size.width  -= 6;
        
        _showImageView = [[UIImageView alloc] initWithFrame:rect];
        [self addSubview:_showImageView];
    }
    
    return self;
}

@end

RootViewController.m
#import "RootViewController.h"
#import "ShowCollectionViewCell.h"
#import "LargeUICollectionViewFlowLayout.h"
#import "YXGCD.h"
#import "SDWebImage.h"

// 重用标示
static NSString *identify = @"ItemIdentifier";

// 数据源
#define SOURCE_DATA @"http://www.duitang.com/album/1733789/masn/p/0/100/"


@interface RootViewController ()<UICollectionViewDelegate, UICollectionViewDataSource>

@property (nonatomic, strong) UICollectionView *collectionView;
@property (nonatomic, strong) NSMutableArray   *dataArray;  // 数据源

@end

@implementation RootViewController


- (void)viewDidLoad
{
    [super viewDidLoad];

    // 初始化数据源
    _dataArray = [[NSMutableArray alloc] init];
    
    // 初始化UICollectionView并指定一个UICollectionViewFlowLayout
    self.collectionView = \
    [[UICollectionView alloc] initWithFrame:self.view.bounds
                       collectionViewLayout:[LargeUICollectionViewFlowLayout new]];
    
    // 给UICollectionViewCell注册重用标示(collectionView会自动给我们创建重用的cell对象)
    [self.collectionView registerClass:[ShowCollectionViewCell class]
            forCellWithReuseIdentifier:@"ItemIdentifier"];
    
    // 设置代理对象
    self.collectionView.delegate   = self;
    self.collectionView.dataSource = self;
    
    // 将UICollectionView添加进父视图
    [self.view addSubview:_collectionView];
    
    
    [[GCDQueue globalQueue] execute:^{
        // 获取json数据
        NSData *data = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:SOURCE_DATA]];
        
        // 转换数据
        NSDictionary *dataDictionary = [NSJSONSerialization JSONObjectWithData:data
                                                                       options:NSJSONReadingMutableLeaves|| NSJSONReadingMutableContainers
                                                                         error:nil];
        if (dataDictionary)
        {
            NSArray *dataArray = dataDictionary[@"data"][@"blogs"];
            for (NSDictionary *dic in dataArray)
            {
                NSLog(@"%@", dic[@"isrc"]);
                
                // 存储数据
                [_dataArray addObject:dic[@"isrc"]];
            }
        }
        
        // 主线程更新
        [[GCDQueue mainQueue] execute:^{
            [self.collectionView reloadData];
        }];
    }];
}

-(NSInteger)collectionView:(UICollectionView *)collectionView
    numberOfItemsInSection:(NSInteger)section
{
    return [_dataArray count];
}

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
                 cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    ShowCollectionViewCell *cell = \
    [collectionView dequeueReusableCellWithReuseIdentifier:@"ItemIdentifier"
                                              forIndexPath:indexPath];
    
    [cell.showImageView setImageWithURL:[NSURL URLWithString:_dataArray[indexPath.row]]];
    
    return cell;
}

@end

效果图如下:

一款显示壁纸的软件就这么搞定雏形了......

 

我们来尝试一下实时更换layout让图片自动布局,效果如下:

源码:

#import "RootViewController.h"
#import "ShowCollectionViewCell.h"
#import "LargeUICollectionViewFlowLayout.h"
#import "AnotherCollectionViewFlowLayout.h"
#import "YXGCD.h"
#import "SDWebImage.h"

// 重用标示
static NSString *identify = @"ItemIdentifier";

// 数据源
#define SOURCE_DATA @"http://www.duitang.com/album/1733789/masn/p/0/100/"


@interface RootViewController ()<UICollectionViewDelegate, UICollectionViewDataSource>

@property (nonatomic, strong) UICollectionView *collectionView;

@property (nonatomic, strong) LargeUICollectionViewFlowLayout *largeLayout;
@property (nonatomic, strong) AnotherCollectionViewFlowLayout *anotherLayout;

@property (nonatomic, strong) NSMutableArray   *dataArray;  // 数据源

@end

@implementation RootViewController


- (void)viewDidLoad
{
    [super viewDidLoad];

    // 初始化数据源
    _dataArray = [[NSMutableArray alloc] init];
    
    // 初始化两种布局
    _largeLayout   = [LargeUICollectionViewFlowLayout new];
    _anotherLayout = [AnotherCollectionViewFlowLayout new];
    
    // 初始化UICollectionView并指定一个UICollectionViewFlowLayout
    self.collectionView = \
    [[UICollectionView alloc] initWithFrame:self.view.bounds
                       collectionViewLayout:_largeLayout];
    
    // 给UICollectionViewCell注册重用标示(collectionView会自动给我们创建重用的cell对象)
    [self.collectionView registerClass:[ShowCollectionViewCell class]
            forCellWithReuseIdentifier:@"ItemIdentifier"];
    
    // 设置代理对象
    self.collectionView.delegate   = self;
    self.collectionView.dataSource = self;
    
    // 将UICollectionView添加进父视图
    [self.view addSubview:_collectionView];
    
    
    [[GCDQueue globalQueue] execute:^{
        // 获取json数据
        NSData *data = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:SOURCE_DATA]];
        
        // 转换数据
        NSDictionary *dataDictionary = [NSJSONSerialization JSONObjectWithData:data
                                                                       options:NSJSONReadingMutableLeaves|| NSJSONReadingMutableContainers
                                                                         error:nil];
        if (dataDictionary)
        {
            NSArray *dataArray = dataDictionary[@"data"][@"blogs"];
            for (NSDictionary *dic in dataArray)
            {
                NSLog(@"%@", dic[@"isrc"]);
                
                // 存储数据
                [_dataArray addObject:dic[@"isrc"]];
            }
        }
        
        // 主线程更新
        [[GCDQueue mainQueue] execute:^{
            [self.collectionView reloadData];
            
            // 3s后切换布局动画
            [[GCDQueue mainQueue] execute:^{
                
                [_largeLayout invalidateLayout];
                [_collectionView setCollectionViewLayout:_anotherLayout
                                                animated:YES];
                
            } afterDelay:NSEC_PER_SEC * 3];
        }];
    }];
}

-(NSInteger)collectionView:(UICollectionView *)collectionView
    numberOfItemsInSection:(NSInteger)section
{
    return [_dataArray count];
}

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
                 cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    ShowCollectionViewCell *cell = \
    [collectionView dequeueReusableCellWithReuseIdentifier:@"ItemIdentifier"
                                              forIndexPath:indexPath];
    
    [cell.showImageView setImageWithURL:[NSURL URLWithString:_dataArray[indexPath.row]]];
    
    return cell;
}

@end

RootViewController.m

AnotherCollectionViewFlowLayout.h + AnotherCollectionViewFlowLayout.m
#import <UIKit/UIKit.h>

@interface AnotherCollectionViewFlowLayout : UICollectionViewFlowLayout

@end


#import "AnotherCollectionViewFlowLayout.h"

@implementation AnotherCollectionViewFlowLayout

- (instancetype)init
{
    self = [super init];
    if (self)
    {
        self.itemSize                = CGSizeMake(150, 200);         // 单元格尺寸
        self.sectionInset            = UIEdgeInsetsMake(0, 0, 0, 0); // 单元格边缘
        self.minimumInteritemSpacing = 10.0f;                        // 横排单元格最小间隔
        self.minimumLineSpacing      = 20.0f;                        // 单元格最小行间距
    }
    return self;
}

@end

几个核心的地方:(布局变化时自动匹配对于UICollectionView很重要哦)

 

so easy :)

目录
相关文章
|
3月前
|
开发者 iOS开发
介绍 UITableView 和 UICollectionView,它们的区别是什么?
介绍 UITableView 和 UICollectionView,它们的区别是什么?
54 0
UINavigationController和UITabBarController合用。
UINavigationController和UITabBarController合用。
52 0
UITableViewCell和UICollectionViewCell自适应高度
UITableView和UICollectionView想通,此处就已UITableView为例
184 0
UITableViewCell和UICollectionViewCell自适应高度
UICollectionview的使用详解
三个代理<UICollectionViewDataSource,UICollectionViewDelegate,UICollectionViewDelegateFlowLayout> 前两个的用法和tableView的很像,第三个是布局的协议。(注意:头视图尾视图都是由代理方法获得,而且需要写注册,缺少了也不行。) 注册以后,就不需要再去管理复用的问题了。这点就很简单。这个如果用好的话,会非常的简单。
UICollectionView的布局
UICollectionView的布局
343 0
UICollectionView的布局