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

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

时间:2015-12-15 18:03:40      阅读:152      评论:0      收藏:0      [点我收藏+]

标签:

  有了上一篇的基础,发现现在常用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

 

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

标签:

原文地址:http://www.cnblogs.com/zyfblog/p/5048841.html

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