UICollectionView简单案例 - 瀑布流

瀑布流

瀑布流的效果就不介绍。直接百度。。。

UICollectionView 是一个强大类似 UITableView 的显示视图,(可能我的理解不是很正确,但可以显示集合数据应该没错)。

瀑布流实现思路,有多列,计算每列高度,将单元格数据追加在短的一列上。

以下使用 UICollectionView 来实现瀑布流。



项目源码

  1. 准备过程
#import "ViewController.h"
#import "MyLayout.h"
#import "ImageModel.h"
#import "MyCell.h"

@interface ViewController () <UICollectionViewDataSource, UICollectionViewDelegate>
{
    UICollectionView *_collectionView;  // 集合视图
    NSMutableArray *_cellDataArray;     // 所有单元格数组对象
    
    NSMutableData *_data;               // 网络数据
}
@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
	
    [self loadData];
    [self createCollectionView];
}

#pragma mark - Data
- (void)loadData
{
    // 初始化对象
    _cellDataArray = [[NSMutableArray alloc] init];
    _data = [[NSMutableData alloc] init];
    
    // 测试数据
    for ( int i = 0 ; i < 20 ; i++ )
    {
        ImageModel *model = [[ImageModel alloc] init];
        model.cellHeight = arc4random()%300 + 50;
        [_cellDataArray addObject:model];
    }
    
} // 加载数据

#pragma mark - View
- (void)createCollectionView
{
    // 创建布局对象,需要对显示图片的布局进行调整所有传递给布局对象
    MyLayout *layout = [[MyLayout alloc] init];
    layout.cellDataArray = _cellDataArray;
    
    // layout 决定来 collectionView 中所有 cell (单元格) 的布局
    _collectionView = [[UICollectionView alloc] initWithFrame:self.view.bounds collectionViewLayout:layout];
    
    _collectionView.dataSource = self;
    _collectionView.delegate = self;
    
    // 创建 集合视图单元格 ,放在重用队列里面
    [_collectionView registerClass:[MyCell class] forCellWithReuseIdentifier:@"cellid"];

    _collectionView.backgroundColor = [UIColor whiteColor];
    [self.view addSubview:_collectionView];

} // 创建集合视图

#pragma mark - UICollectionViewDataSource
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
    return _cellDataArray.count;
} // 单元格总个数

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    // 重用队列中获取单元格
    MyCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"cellid" forIndexPath:indexPath];
    
    [cell fillCellData:_cellDataArray[indexPath.row]];
    return cell;
    
} // 所有单元格
@end

  1. 三个辅助类
  1. 布局类,每一个单元格都需要根据高度进行布局,将高度较小的追加在短的一边
  2. 单元格类, 用于显示数据的单元格
  3. 数据模型类,保存数据

#import <UIKit/UIKit.h>

// 布局类
@interface MyLayout : UICollectionViewLayout

@property (nonatomic, strong) NSMutableArray *cellDataArray; // 所有对象数组,

@end

#import "MyLayout.h"
#import "ImageModel.h"

@implementation MyLayout
/**
 *  集合视图布局有三个方法必须实现
 */

- (CGSize)collectionViewContentSize
{
    /**
     *  思路:需要确定是左右两边视图高度,哪一个高,将单元格视图追加在高度较小的一边。
     */

    CGFloat leftHeight = 0.0;
    CGFloat rightHeight = 0.0;
    
    for ( int i = 0 ; i < _cellDataArray.count ; i++)
    {
        CGFloat h = [_cellDataArray[i] cellHeight];
        
        if (leftHeight <= rightHeight) // 将左右单元格高度分开
        {
            leftHeight += h;
        }
        else
        {
            rightHeight += h;
        }
    }

    return CGSizeMake(0, leftHeight > rightHeight ? leftHeight : rightHeight);
    
} // 返回 collectionView 的内容的大小,用于显示

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
    /**
     *  需要循环调用每一个单元格的属性方法,用于设置
     */
    
    NSMutableArray *array = [[NSMutableArray alloc] init];
    
    // 这里只有一个段,段属性和 UITableView 类似
    for ( int i = 0 ; i < [self.collectionView numberOfItemsInSection:0] ; i++)
    {
        NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:0];
        
        [array addObject:[self layoutAttributesForItemAtIndexPath:indexPath]];
    }
    
    return array;
    
} // 返回包含所有 cell 的属性的数组

- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
    UICollectionViewLayoutAttributes *attr = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
    
    // 两个属性
    // 单元格大小
    CGFloat cellHeight = [_cellDataArray[indexPath.row] cellHeight];
    attr.size = CGSizeMake(160, cellHeight);
    
    // 单元格位置
    CGFloat leftHeight = 0.0;
    CGFloat rightHeight = 0.0;
    
    for ( int i = 0 ; i < indexPath.row ; i++ )
    {
        CGFloat h = [_cellDataArray[i] cellHeight];
        
        if (leftHeight <= rightHeight)
        {
            leftHeight += h;
        }
        else
        {
            rightHeight += h;
        }
    }
    
    if (leftHeight <= rightHeight)
    {
        attr.center = CGPointMake( 80, leftHeight + cellHeight / 2 );
    }
    else
    {
        attr.center = CGPointMake( 240, rightHeight + cellHeight / 2 );
    }
    
    return attr; 
    
} // 返回每一个 cell 对应的属性

@end
#import <UIKit/UIKit.h>

@class ImageModel;

@interface MyCell : UICollectionViewCell

/**
 *  填充单元格数据
 *
 *  @param model 图片模型
 */
- (void)fillCellData:(ImageModel *)model;

@end

#import "MyCell.h"
#import "ImageModel.h"

@implementation MyCell
{
    UIImageView *_imgView;
}

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self)
    {
        _imgView = [[UIImageView alloc] init];
        [self.contentView addSubview:_imgView];
    }
    return self;
}

- (void)fillCellData:(ImageModel *)model
{
    _imgView.frame = CGRectMake(5, 5, 150, self.contentView.bounds.size.height - 10);
    _imgView.backgroundColor = [UIColor colorWithRed:(arc4random() % 10 * 0.1) green:(arc4random() % 10 * 0.1) blue:(arc4random() % 10 * 0.1) alpha:0.5];
}

@end
#import <Foundation/Foundation.h>

// 数据模型
@interface ImageModel : NSObject

@property (nonatomic,copy)   NSString  *imgUrl;     // 图片网络路径
@property (nonatomic,assign) CGFloat    imgHeight;  // 图片高度
@property (nonatomic,assign) CGFloat    imgWidth;   // 图片宽度
@property (nonatomic,assign) CGFloat    cellHeight; // 单元格高度

@end

  1. 页面效果

   


加载网络数据

布局方法不需要修改,修改数据填充方法

使用SDWebImage开源库

-(void)fillData:(ImageModel *)model
{
    _imgv.frame = CGRectMake(5, 5, 150, self.contentView.bounds.size.height - 10);
    _imgv.backgroundColor = [UIColor colorWithRed:(arc4random() % 8)*0.1 green:(arc4random() % 8)*0.1 blue:(arc4random() % 8)*0.1 alpha:1];
    
    [_imgv setImageWithURL:[NSURL URLWithString:model.imgUrl]];
    
}

获取网络数据的具体实现有很多种办法,这里就不给出了。

我已上传源代码

http://download.csdn.net/detail/a274275605/8120707

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值