#import <UIKit/UIKit.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@end
#import "AppDelegate.h"
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
return YES;
}
@end
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
@end
#import "ViewController.h"
#import "WaterFlowLayout.h"
#import "ImageCell.h"
#import "Model.h"
#import "UIImageView+WebCache.h" //sd分类.导入第三方类库.
@interface ViewController ()<WaterFlowLayoutDelegate, UICollectionViewDelegate, UICollectionViewDataSource>
@property (nonatomic, strong) NSMutableArray *dataArray;
@end
@implementation ViewController
- (void)setData{
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"Data" ofType:@"json"];
NSData *data = [NSData dataWithContentsOfFile:filePath];
NSArray *rootArray = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
self.dataArray = [NSMutableArray array];
for (NSDictionary *dic in rootArray) {
Model *model = [[Model alloc] init];
[model setValuesForKeysWithDictionary:dic];
[_dataArray addObject:model];
}
}
- (void)viewDidLoad {
[super viewDidLoad];
[self setData];
WaterFlowLayout *waterFlowLayout = [[WaterFlowLayout alloc] init];
waterFlowLayout.numberOfColumn = 3;
waterFlowLayout.insertItemSpacing = 10;
waterFlowLayout.sectionInsets = UIEdgeInsetsMake(20, 20, 20, 20);
CGFloat width = ([UIScreen mainScreen].bounds.size.width - 2 * 20 - 10 * 2) / 3;
waterFlowLayout.itemSize = CGSizeMake(width, width);
waterFlowLayout.delegate = self;
UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:[UIScreen mainScreen].bounds collectionViewLayout:waterFlowLayout];
collectionView.delegate = self;
collectionView.dataSource = self;
[collectionView registerClass:[ImageCell class] forCellWithReuseIdentifier:@"cell"];
[self.view addSubview:collectionView];
}
#pragma mark----------dataSource--------
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return _dataArray.count;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
ImageCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"cell" forIndexPath:indexPath];
Model *model = _dataArray[indexPath.item];
[cell.myImageView sd_setImageWithURL:[NSURL URLWithString:model.thumbURL]];
return cell;
}
#pragma mark----------瀑布流代理方法---------
- (CGFloat)heightForItemIndexPath:(NSIndexPath *)indexPath {
Model *model = _dataArray[indexPath.item];
CGFloat width = ([UIScreen mainScreen].bounds.size.width - 2 * 20 - 10 * 2) / 3;
CGFloat height = width * model.height / model.width;
return height;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
@end
#import <UIKit/UIKit.h>
@protocol WaterFlowLayoutDelegate <NSObject>
- (CGFloat)heightForItemIndexPath:(NSIndexPath *)indexPath;
@end
@interface WaterFlowLayout : UICollectionViewLayout
@property (nonatomic, assign) CGSize itemSize;
@property (nonatomic, assign) CGFloat insertItemSpacing;
@property (nonatomic, assign) UIEdgeInsets sectionInsets;
@property (nonatomic, assign) NSInteger numberOfColumn;
@property (nonatomic, assign) id<WaterFlowLayoutDelegate> delegate;
@end
#import "WaterFlowLayout.h"
@interface WaterFlowLayout ()
@property (nonatomic, assign) NSInteger numberOfItems;
@property (nonatomic, strong) NSMutableArray *columnHeights;
@property (nonatomic, strong) NSMutableArray *itemAttributes;
- (NSInteger)indexForLongestColumn;
- (NSInteger)indexForShortestColumn;
@end
@implementation WaterFlowLayout
- (NSMutableArray *)columnHeights {
if (!_columnHeights) {
self.columnHeights = [NSMutableArray array];
}
return _columnHeights;
}
- (NSMutableArray *)itemAttributes {
if (!_itemAttributes) {
self.itemAttributes = [NSMutableArray array];
}
return _itemAttributes;
}
- (NSInteger)indexForLongestColumn {
NSInteger longestIndex = 0;
NSInteger longestHeight = 0;
for (int i = 0; i < _columnHeights.count; i++) {
CGFloat currentHeight = [_columnHeights[i] floatValue];
if (currentHeight > longestHeight) {
longestHeight = currentHeight;
longestIndex = i;
}
}
return longestIndex;
}
- (NSInteger)indexForShortestColumn {
NSInteger shortestIndex = 0;
CGFloat shortestHeight = CGFLOAT_MAX;
for (int i = 0; i < _columnHeights.count; i++) {
CGFloat currentHeight = [_columnHeights[i] floatValue];
if (currentHeight < shortestHeight) {
shortestHeight = currentHeight;
shortestIndex = i;
}
}
return shortestIndex;
}
- (void)prepareLayout {
[super prepareLayout];
for (int i = 0; i < _numberOfColumn; i++) {
self.columnHeights[i] = @(self.sectionInsets.top);
}
self.numberOfItems = [self.collectionView numberOfItemsInSection:0];
for (int i = 0; i < _numberOfItems; i++) {
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:0];
UICollectionViewLayoutAttributes *layoutAttributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
NSInteger shortestIndex = [self indexForShortestColumn];
CGFloat shortestHeight = [_columnHeights[shortestIndex] floatValue];
CGFloat itemX = _sectionInsets.left + (_itemSize.width + _insertItemSpacing) * shortestIndex;
CGFloat itemY = shortestHeight + _insertItemSpacing;
CGFloat itemWidth = _itemSize.width;
CGFloat itemHeight = 0;
if (_delegate != nil && [_delegate respondsToSelector:@selector(heightForItemIndexPath:)]) {
itemHeight = [_delegate heightForItemIndexPath:indexPath];
}
layoutAttributes.frame = CGRectMake(itemX, itemY, itemWidth, itemHeight);
[self.itemAttributes addObject:layoutAttributes];
self.columnHeights[shortestIndex] = @(itemY + itemHeight);
}
}
- (CGSize)collectionViewContentSize {
NSInteger longestIndex = [self indexForLongestColumn];
CGFloat longestHeight = [self.columnHeights[longestIndex] floatValue];
CGSize contentSize = self.collectionView.frame.size;
contentSize.height = longestHeight;
return contentSize;
}
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect {
return self.itemAttributes;
}
@end
#import <UIKit/UIKit.h>
@interface ImageCell : UICollectionViewCell
@property (nonatomic,strong)UIImageView *myImageView;
@end
#import "ImageCell.h"
@implementation ImageCell
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.myImageView = [[UIImageView alloc] initWithFrame:self.bounds];
[self.contentView addSubview:_myImageView];
}
return self;
}
- (void)layoutSubviews
{
[super layoutSubviews];
self.myImageView.frame = self.bounds;
}
@end
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@interface Model : NSObject
@property(nonatomic, copy) NSString *thumbURL;
@property(nonatomic, assign) CGFloat width;
@property(nonatomic, assign) CGFloat height;
@end
#import "Model.h"
@implementation Model
-(void)setValue:(id)value forUndefinedKey:(NSString *)key
{
}
-(void)setValue:(id)value forKey:(NSString *)key
{
[super setValue:value forKey:key];
if ([key isEqualToString:@"width"]) {
self.width = [value floatValue];
}
if ([key isEqualToString:@"height"]) {
self.height = [value floatValue];
}
}
@end