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

  • 相关阅读:
    C#操作Windows控制面板
    WPF打印控件内容
    LINQ函数
    通过实现System.IComparable接口的CompareTo方法对两个类进行比较
    泛型和约束
    CSS样式基础总结
    C#调用百度高精度IP定位API通过IP获取地址
    软件下载路径
    RNN学习资料
    mysql 不能插入中文记录
  • 原文地址:https://www.cnblogs.com/YouXianMing/p/3737121.html
Copyright © 2020-2023  润新知