码迷,mamicode.com
首页 > 其他好文 > 详细

瀑布流的简单自定义

时间:2015-04-26 16:31:58      阅读:177      评论:0      收藏:0      [点我收藏+]

标签:

 

 

#import <UIKit/UIKit.h>

@class UICollectionViewFlowWaterLayout;

@protocol UICollectionViewFlowWaterDelegate <UICollectionViewDelegate>

- (CGFloat)collectionView:(UICollectionView *)c layout:(UICollectionViewFlowWaterLayout *)collectionViewLayout heightForItemAtIndextPath:(NSIndexPath*)p;

//这里需要代理返回区头的高

-(CGFloat)collectionView:(UICollectionView *)c layoutWithHeader:(UICollectionViewFlowWaterLayout *)collectionViewLayout heightForHeaderAtIndextPath:(NSIndexPath*)indexPath;

 

@end

 

@interface UICollectionViewFlowWaterLayout : UICollectionViewLayout

 

 

@property (nonatomic,assign) NSInteger HeaderHeight;

 

//列数

@property (nonatomic,assign) NSInteger columnCount;

//每一个 item 的宽度

@property (nonatomic,assign) CGFloat itemWidth;

//每个 section 的偏移量

@property (nonatomic,assign) UIEdgeInsets sectionInset;

@property (nonatomic,assign) id<UICollectionViewFlowWaterDelegate> delegate;

@end

------------------------------------

#import "UICollectionViewFlowWaterLayout.h"

@interface UICollectionViewFlowWaterLayout ()

//记录当前的item 个数

@property (nonatomic,assign) NSInteger itemCount;

//记录间隙的宽度

@property (nonatomic,assign) CGFloat interitemSpacing;

//用来记录每一列的高度

@property (nonatomic,retain) NSMutableArray *columnHeights;

@property (nonatomic,retain) NSMutableArray *attributes;

 

@property (nonatomic,assign)NSInteger HeaderWithHeight;

 

@end

 

@implementation UICollectionViewFlowWaterLayout

 

- (void)dealloc {

    self.columnHeights = nil;

    self.attributes = nil;

    [super dealloc];

}

 

- (id)init {

    self = [super init];

    if (self) {

        [self initData];

    }

    return self;

}

 

- (void)initData {

    _itemWidth      = 140.0f;

    _columnCount    = 2;

    _sectionInset   = UIEdgeInsetsZero;

}

 

 

- (void)setColumnCount:(NSInteger)columnCount {

    if (_columnCount != columnCount) {

        _columnCount = columnCount;

        //调用 ‘invalidateLayout’ 不会使布局立即响应, collection View 会检查当前布局是否是最新布局,如果不是则更新。也就是说多次调用 ‘invalidateLayout’ 不会引起布局的重复更新;

        [self invalidateLayout];

    }

}

 

- (void)setItemWidth:(CGFloat)itemWidth {

    if (_itemWidth != itemWidth) {

        _itemWidth = itemWidth;

        [self invalidateLayout];

    }

}

 

- (void)setSectionInset:(UIEdgeInsets)sectionInset {

    if (!UIEdgeInsetsEqualToEdgeInsets(_sectionInset, sectionInset)) {

        _sectionInset = sectionInset;

        [self invalidateLayout];

    }

}

 

#pragma mark - Override

//预先计算需要提供 布局信息 告诉 collection View 每个 item 的绘画属性

//用layout 对象调用invalidateLayout 来开始布局过程,首先会调用prepareLayout

- (void)prepareLayout {

    [super prepareLayout];

    

    //首先要获取collection View 当前section上的item 的个数

    

    _itemCount = [[self collectionView] numberOfItemsInSection:0];

    //断言 不足一列 就报错

    NSAssert(_columnCount > 1, @"当前瀑布流的列数必须大于1");

    

    //开始布局设置每一个item 的位置坐标和属性绘画

    

    //拿到当前绘制collection view 内容的宽度

    //也即是在多宽的位置上绘制

    

    CGFloat width = self.collectionView.frame.size.width - _sectionInset.left -_sectionInset.right;

    //计算一个间隙的宽度

    _interitemSpacing = floorf(width - _columnCount*_itemWidth)/(_columnCount - 1);

  

    self.attributes = [NSMutableArray arrayWithCapacity:_itemCount];

    self.columnHeights = [NSMutableArray arrayWithCapacity:_columnCount];

    

    for (NSInteger idx = 0; idx < _columnCount; idx++) {

//        _columnHeights[idx] = @(_sectionInset.top);

        

        [_columnHeights addObject:@(_sectionInset.top)];

    }

    NSLog(@"%@",_columnHeights);

    //配置 每一个item 的绘制属性

 

    //遍历下标

    for (NSInteger idx = 0; idx < _itemCount; idx++) {

        NSIndexPath *indexPath = [NSIndexPath indexPathForItem:idx inSection:0];

        

        //拿到item 的高度

        CGFloat itemHeight = [self.delegate collectionView:self.collectionView layout:self heightForItemAtIndextPath:indexPath];

        //获取最低列的位置

        NSInteger columnIdex = [self getMinHeightColumnIndex];

        //设置没有个item 的xy

        

        CGFloat xOffset = _sectionInset.left + (_itemWidth+_interitemSpacing)*columnIdex;

        CGFloat yOffset = [(_columnHeights[columnIdex]) floatValue];

        //设置每一个item 的绘画特性

    //区头的高,非常重要,添加到attributesItem上面

        _HeaderWithHeight =[self.delegate collectionView:self.collectionView layoutWithHeader:self heightForHeaderAtIndextPath:indexPath];

        

        UICollectionViewLayoutAttributes *attributesItem = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];

        attributesItem.frame = CGRectMake(xOffset, yOffset+_HeaderWithHeight, _itemWidth, itemHeight);

        

        [_attributes addObject:attributesItem];

        _columnHeights[columnIdex] = @(yOffset + itemHeight + _interitemSpacing);

        }

 

}

 

- (CGSize)collectionViewContentSize {

    

    if (0 == self.itemCount) {

        return CGSizeZero;

    }

    //这里需要返回一下区头的高度不然拉表的时候会有问题

    CGSize contentSize = self.collectionView.frame.size;

    NSInteger columnMaxIndex = [self getMaxHeightColumnIndex];

    contentSize.height = [self.columnHeights[columnMaxIndex] floatValue] + self.sectionInset.bottom - self.interitemSpacing + _HeaderWithHeight;

   

    return contentSize;

    

}

 

- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath {

    return (self.attributes)[indexPath.item];

}

 

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect {

    return [self.attributes filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {

        return CGRectIntersectsRect(rect,((UICollectionViewLayoutAttributes *)evaluatedObject).frame);

    }]];

}

 

- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds{

    return NO;

}

 

//find out min column index

- (NSInteger)getMinHeightColumnIndex {

    

    __block NSInteger index = 0;

    __block CGFloat tempIndex = MAXFLOAT;

    

    [self.columnHeights enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {

        

        CGFloat temp = [obj floatValue];

        if (temp < tempIndex) {

            tempIndex = temp;

            index = idx;

        }

        

    }];

    

    return index;

}

 

//find out max column index

- (NSInteger)getMaxHeightColumnIndex {

    

    __block NSInteger index = 0;

    __block CGFloat tempIndex = 0;

    

    NSLog(@"%@",self.columnHeights);

    [self.columnHeights enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {

        

        CGFloat temp = [obj floatValue];

        if (temp > tempIndex) {

            tempIndex = temp;

            index = idx;

        }

        

    }];

    

    return index;

}

 

@end

 --------具体的实现-----上面是自定义的cell 

#import "ViewController.h"

#import "UICollectionViewFlowWaterLayout.h"

 

@interface ViewController ()<UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewFlowWaterDelegate>{

    

}

 

 

@end

 

@implementation ViewController

 

- (void)viewDidLoad {

    [super viewDidLoad];

    

    UICollectionViewFlowWaterLayout *layout = [[UICollectionViewFlowWaterLayout alloc]init];

    layout.columnCount = 2;

    layout.itemWidth   = 150.0f;

    layout.delegate    = self;

    

    UICollectionView *collection = [[UICollectionView alloc]initWithFrame:self.view.bounds collectionViewLayout:layout];

    [collection registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"kCellID"];

    collection.backgroundColor = [UIColor redColor];

    collection.dataSource = self;

    collection.delegate   = self;

    

    [self.view addSubview:collection];

    

    

    

}

 

- (void)didReceiveMemoryWarning {

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

 

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {

    return 10;

}

 

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {

    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"kCellID" forIndexPath:indexPath];

    cell.backgroundColor = [UIColor yellowColor];

    

    return cell;

}

#pragma  mark --------------代理-----------------

//这里自定义区头的高度,同理可以自定义区尾这里非常重要

-(CGFloat)collectionView:(UICollectionView *)c layoutWithHeader:(UICollectionViewFlowWaterLayout *)collectionViewLayout heightForHeaderAtIndextPath:(NSIndexPath*)indexPath

{

    CGFloat height = arc4random()%200 + 100.0f;

    return height;

}

 

- (CGFloat)collectionView:(UICollectionView *)c layout:(UICollectionViewFlowWaterLayout *)collectionViewLayout heightForItemAtIndextPath:(NSIndexPath *)p {

    CGFloat height = arc4random()%200 + 50.0f;

    

    return height;

}

-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath

{

    NSLog(@"%ld",(long)indexPath.row);

}

@end

 

瀑布流的简单自定义

标签:

原文地址:http://www.cnblogs.com/zhuzibaijai/p/4457858.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!