Skip to content

Instantly share code, notes, and snippets.

@VivekMolkar
Created November 26, 2017 13:12
Show Gist options
  • Save VivekMolkar/31cb10999e8ef5598c0f19449128c6f5 to your computer and use it in GitHub Desktop.
Save VivekMolkar/31cb10999e8ef5598c0f19449128c6f5 to your computer and use it in GitHub Desktop.
//
// DynamicHeightLayout.m
// DynamicHeightLayout
//
// Created by Vivek Molkar on 26/11/17.
// Copyright © 2017 Vivek Molkar. All rights reserved.
//
#import "DynamicHeightLayout.h"
@interface DynamicHeightLayout()
@property int numberOfColumns;
@property CGFloat cellPadding;
@property NSMutableArray *cache;
@property CGFloat contentHeight;
@property CGFloat contentWidth;
@end
@implementation DynamicHeightLayout
- (id) init {
NSLog(@"init");
if((self = [super init]))
[self initialize];
return self;
}
- (id) initWithCoder:(NSCoder *)aDecoder {
NSLog(@"initWithCoder:");
if((self = [super initWithCoder:aDecoder]))
[self initialize];
return self;
}
- (void) initialize {
NSLog(@"initialize");
self.numberOfColumns = 2;
self.contentHeight = 0;
self.cellPadding = 10;
self.cache = [NSMutableArray new];
}
- (void) prepareLayout {
if (self.cache.count == 0) {
UIEdgeInsets insets = self.collectionView.contentInset;
self.contentWidth = self.collectionView.bounds.size.width - (insets.left + insets.right);
CGFloat columnWidth = self.contentWidth / self.numberOfColumns;
NSMutableArray *xOffsets = [NSMutableArray new];
NSMutableArray *yOffsets = [NSMutableArray new];
for (int i = 0; i < self.numberOfColumns; i++) {
[xOffsets addObject: @(i * columnWidth)];
[yOffsets addObject: @(0)];
}
int column = 0;
for (int i = 0; i < [self.collectionView numberOfItemsInSection:0]; i++) {
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:0];
CGFloat cellHeight = arc4random_uniform(200);
CGFloat height = self.cellPadding * 2 + cellHeight;
CGRect frame = CGRectMake((CGFloat)[[xOffsets objectAtIndex:column] floatValue],
(CGFloat)[[yOffsets objectAtIndex:column] floatValue],
columnWidth,
height);
CGRect insetFrame = CGRectInset(frame, self.cellPadding, self.cellPadding);
UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
attributes.frame = insetFrame;
[self.cache addObject:attributes];
self.contentHeight = MAX(self.contentHeight, CGRectGetMaxY(frame));
[yOffsets replaceObjectAtIndex:column withObject:@([[yOffsets objectAtIndex:column]floatValue] + height)];
column = column < (self.numberOfColumns - 1) ? (column + 1) : 0;
}
}
}
- (CGSize) collectionViewContentSize {
return CGSizeMake(self.contentWidth, self.contentHeight);
}
- (UICollectionViewLayoutAttributes *) layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath {
return [self.cache objectAtIndex:indexPath.item];
}
- (NSArray<UICollectionViewLayoutAttributes *> *) layoutAttributesForElementsInRect:(CGRect)rect {
NSMutableArray *visibleAttributes = [[NSMutableArray alloc] init];
for (UICollectionViewLayoutAttributes *attributes in self.cache) {
if (CGRectIntersectsRect(attributes.frame, rect)) {
[visibleAttributes addObject:attributes];
}
}
return visibleAttributes;
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment