加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

iOS开发之不规则流布局UICollectionViewLayout自定义布局

(2016-02-23 21:02:36)

WaterFlowLayout.h

//
//  WaterFlowLayout.h
//  LessonCustomLayout
//
//  Created by 陈清源 on 15/5/13.
//  Copyright (c) 2015 cq. All rights reserved.
//

#import
@class WaterFlowLayout;

@protocol WaterFlowLayoutDelegate <</span>NSObject>

//关键方法,此方法的作用是返回每一个itemsize大小
- (
CGSize)collectionView:(UICollectionView *)collectionView layout:(WaterFlowLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath;

- (
UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(WaterFlowLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section;

- (
CGFloat)collectionView:(UICollectionView *)collectionView layout:(WaterFlowLayout *)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section;

- (
CGFloat)collectionView:(UICollectionView *)collectionView layout:(WaterFlowLayout *)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section;

@end

@interface WaterFlowLayout : UICollectionViewLayout

//瀑布流一共多少列
@property (nonatomic, assign) NSUInteger numberOfColumn;

@property (nonatomic, assign) id<</span>WaterFlowLayoutDelegate>delegate;

@end








WaterFlowLayout.m
//
//  WaterFlowLayout.m
//  LessonCustomLayout
//
//  Created by 陈清源 on 15/5/13.
//  Copyright (c) 2015 cq. All rights reserved.
//

#import "WaterFlowLayout.h"

@interface WaterFlowLayout ()

//存放每一列的高度
@property (nonatomic, retain) NSMutableArray *columnHeightsArray;

//存放 每一个item 属性 包含 frame以及下标
@property (nonatomic, retain) NSMutableArray *attributesArray;

@end

@implementation WaterFlowLayout

//获取最小高度的方法
- (
CGFloat)minHeight
{
   
CGFloat min = 100000;
   
for (NSNumber *height in _columnHeightsArray) {
       
CGFloat h = [height floatValue];
       
if (min > h) {
            min = h;
        }
    }
   
return min;
}

//获取最大值
- (
CGFloat)maxHeight
{
   
CGFloat max = 0;
   
for (NSNumber *height in _columnHeightsArray) {
       
CGFloat h = [height floatValue];
       
if (max < h) {
            max = h;
        }
    }
   
return max;
}

- (
NSUInteger)indexOfMinHeight
{
   
NSUInteger index = 0;
   
for (int i = 0; i < [_columnHeightsArray count]; i ++) {
       
CGFloat height = [_columnHeightsArray[i] floatValue];
       
if (height == [self minHeight]) {
            index = i;
           
return index;
        }
    }
   
return index;
}

//重写父类的布局方法
- (
void)prepareLayout
{
    [
super prepareLayout];
   
   
_attributesArray = [[NSMutableArray alloc] init];
   
   
_columnHeightsArray = [[NSMutableArray alloc] initWithCapacity:self.numberOfColumn];
   
   
//给列高数组里面的对象赋初值
   
for (int i = 0; i <</span> self.numberOfColumn; i ++) {
        [
_columnHeightsArray addObject:@0.0];
    }
   
   
CGFloat totalWidth = self.collectionView.frame.size.width;
   
   
//创建 每个item frame中的xy
   
CGFloat x = 0;
   
CGFloat y = 0;
   
   
NSUInteger itemCount = [self.collectionView numberOfItemsInSection:0];
   
   
for (int i = 0; i < itemCount; i ++) {
       
//得到集合视图中 列间隙的个数
       
NSUInteger numberOfSpace = self.numberOfColumn - 1;
       
       
//代理对象执行代理方法,得到 item之间的间隙大小
       
CGFloat spaceWidth = [_delegate collectionView:self.collectionView layout:self minimumInteritemSpacingForSectionAtIndex:0];
       
       
//求每列的宽度,也就是每个itemwidth
       
CGFloat width = (totalWidth - spaceWidth * numberOfSpace) / self.numberOfColumn;
       
       
       
//获取每一个itemSize的大小
       
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:0];
       
       
//数据中原始图片大小
       
CGSize imageSize = [_delegate collectionView:self.collectionView layout:self sizeForItemAtIndexPath:indexPath];
   
       
//通过 约分公式得到固定宽之后的高度是多少
       
CGFloat height = width * imageSize.height / imageSize.width;
       
       
       
UICollectionViewLayoutAttributes *attribute = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
       
       
//记录每一个item的大小和位置
        attribute.
frame = CGRectMake(x, y, width, height);
       
       
//数组保存每个item的位置信息
        [
_attributesArray addObject:attribute];
       
       
NSLog(@"item = %d",i);
       
NSLog(@"x = %.2f y = %.2f width = %.2f height = %.2f",x,y,width,height);
       
       
//求列高最小的那一列的下标
       
NSUInteger minHeightIndex = [self indexOfMinHeight];
       
       
//求出最小列的高度
       
CGFloat minHeight = [_columnHeightsArray[minHeightIndex] floatValue];
       
       
//求出行高
       
CGFloat lineHeight = [_delegate collectionView:self.collectionView layout:self minimumLineSpacingForSectionAtIndex:0];
       
       
//上一次总的列高 加上 行高 加上新加上的itemheight,才是现在这一列的总高度
       
//minHeight为最小列现在的高度
       
//lineHeight为行间距
       
//height为新加的item的高
       
_columnHeightsArray[minHeightIndex] = [NSNumber numberWithFloat:minHeight + lineHeight + height];
       
       
//重新算最小列高的下标
        minHeightIndex = [
self indexOfMinHeight];
       
       
//算下一次新加的itemxy
        x = (spaceWidth + width) * minHeightIndex;
       
        y = [
self minHeight];
    }
}

//重写这个方法,可以返回集合视图的总高度
- (
CGSize)collectionViewContentSize
{
   
return CGSizeMake(self.collectionView.frame.size.width, [self maxHeight]);
}

//这个方法不写 集合视图显示不出来,这个方法是将保存的每个item的信息告诉集合视图,进行显示。
- (
NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
   
return _attributesArray;
}






@end

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有