使用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 :)

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM