UICollectionView的简单使用(二)— 瀑布流(石工布局)

  有了上一篇的基础,发现现在常用UICollectionView的布局是瀑布流(石工布局),首先我看看默认大小不一的布局。

1.默认布局

  我们在ViewController.m文件添加一下代码

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
    CGFloat randomHeight = 100 + (arc4random() % 140);
    return CGSizeMake(100, randomHeight);//100-240之间
}

  模拟器运行如下:

  这就是默认的情况,但不是我们想要的情况。

2.瀑布流(石工布局)

  接下来就要创建一个UICollectionViewLayout的子类,布局子类覆盖父类的方法

  

2.1 在YFCollectionViewLayout.h文件中添加

#import <UIKit/UIKit.h>

@class YFCollectionViewLayout;

@protocol YFCollectionViewLayoutDelegate <NSObject>
@required
- (CGFloat)collectionView:(UICollectionView *) collectionView
                   layout:(YFCollectionViewLayout *)layout
 heightForItemAtIndexPath:(NSIndexPath *) indexPath;

@end

@interface YFCollectionViewLayout : UICollectionViewLayout
/**
 *  列数
 */
@property (nonatomic, assign) NSUInteger numberOfColumns;
/**
 *  间距
 */
@property (nonatomic, assign) CGFloat interItemSpacing;
@property (nonatomic, weak)  id<YFCollectionViewLayoutDelegate> delegate;

@end

2.2  在YFCollectionViewLayout.m文件中

子类需要覆盖的方法有

/**
 *  布局准备方法,可以把一些计算的东西放到这里
 */
- (void)prepareLayout;
/**
 *  每个子控件的一些属性
 */
- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect;
/**
 *  集合视图整体大小
 *
 */
- (CGSize)collectionViewContentSize;
//
//  YFCollectionViewLayout.m
//  WaterfallFlowCollection
//
//  Created by apple on 15/12/15.
//  Copyright © 2015年 蓝天的梦想. All rights reserved.
//

#import "YFCollectionViewLayout.h"

@interface YFCollectionViewLayout ()
/**
 *  最后列的Y值
 */
@property (nonatomic, strong) NSMutableDictionary *lastYValueForColumn;
/**
 * 布局信息
 */
@property (nonatomic, strong) NSMutableDictionary *layoutInfo;
@end

@implementation YFCollectionViewLayout

/**
 *  布局准备方法,可以把一些计算的东西放到这里
 */
-(void) prepareLayout {
    
     [super prepareLayout];
    
    self.lastYValueForColumn = [NSMutableDictionary dictionary];
    CGFloat currentColumn = 0;
    CGFloat fullWidth = self.collectionView.frame.size.width;
    CGFloat availableSpaceExcludingPadding = fullWidth - (self.interItemSpacing * (self.numberOfColumns + 1));
    CGFloat itemWidth = availableSpaceExcludingPadding / self.numberOfColumns;
    self.layoutInfo = [NSMutableDictionary dictionary];
    NSIndexPath *indexPath;
    NSInteger numSections = [self.collectionView numberOfSections];
    
    for(NSInteger section = 0; section < numSections; section++)  {
        
        NSInteger numItems = [self.collectionView numberOfItemsInSection:section];
        for(NSInteger item = 0; item < numItems; item++){
            indexPath = [NSIndexPath indexPathForItem:item inSection:section];
            
            UICollectionViewLayoutAttributes *itemAttributes =
            [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
            
            CGFloat x = self.interItemSpacing + (self.interItemSpacing + itemWidth) * currentColumn;
            CGFloat y = [self.lastYValueForColumn[@(currentColumn)] doubleValue];
            CGFloat height = [((id<YFCollectionViewLayoutDelegate>)self.collectionView.delegate)
                              collectionView:self.collectionView
                              layout:self
                              heightForItemAtIndexPath:indexPath];
            
            itemAttributes.frame = CGRectMake(x, y, itemWidth, height);
            y+= height;
            y += self.interItemSpacing;
            
            self.lastYValueForColumn[@(currentColumn)] = @(y);
            
            currentColumn ++;
            if(currentColumn == self.numberOfColumns) currentColumn = 0;
            self.layoutInfo[indexPath] = itemAttributes;
        }
    }
}

/**
 *  每个子控件的一些属性
 */
- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect{
   NSMutableArray *allAttributes = [NSMutableArray arrayWithCapacity:self.layoutInfo.count];
    
    [self.layoutInfo enumerateKeysAndObjectsUsingBlock:^(NSIndexPath *indexPath,
                                                         UICollectionViewLayoutAttributes *attributes,
                                                         BOOL *stop) {
        
        if (CGRectIntersectsRect(rect, attributes.frame)) {
            [allAttributes addObject:attributes];
        }
    }];
    return allAttributes;
}

/**
 *  集合视图整体大小
 *
 */
-(CGSize) collectionViewContentSize {
    
    NSUInteger currentColumn = 0;
    CGFloat maxHeight = 0;
    do {
        CGFloat height = [self.lastYValueForColumn[@(currentColumn)] doubleValue];
        if(height > maxHeight)
            maxHeight = height;
        currentColumn ++;
    } while (currentColumn < self.numberOfColumns);
    
    return CGSizeMake(self.collectionView.frame.size.width, maxHeight);
}

@end

打开Storyboard的文件,给CollectionViewLayout设置类名

打开ViewCollection.m文件,拖线并设置代理

设置间距和列数

设置代理方法

模拟器运行结果如下

 

下载地址:https://github.com/yifazhang/WaterfallFlowCollection

 

posted @ 2015-12-15 17:17  蓝天的梦想  阅读(875)  评论(0编辑  收藏  举报