Skip to content

Commit

Permalink
Merge branch 'release/0.9'
Browse files Browse the repository at this point in the history
  • Loading branch information
chiahsien committed May 7, 2015
2 parents 8d29387 + 88801dd commit 7d8ee86
Show file tree
Hide file tree
Showing 34 changed files with 1,985 additions and 28 deletions.
28 changes: 28 additions & 0 deletions CHTCollectionViewWaterfallLayout.h
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,25 @@ extern NSString *const CHTCollectionElementKindSectionFooter;
*/
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section;

/**
* Asks the delegate for the minimum spacing between colums in a secified section. If this method is not implemented, the
* minimumColumnSpacing property is used for all sections.
*
* @param collectionView
* The collection view object displaying the waterfall layout.
* @param collectionViewLayout
* The layout object requesting the information.
* @param section
* The index of the section whose minimum interitem spacing is being requested.
*
* @discussion
* If you do not implement this method, the waterfall layout uses the value in its minimumColumnSpacing property to determine the amount of space between columns in each section.
*
* @return
* The minimum spacing between each column.
*/
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumColumnSpacingForSectionAtIndex:(NSInteger)section;

@end

#pragma mark - CHTCollectionViewWaterfallLayout
Expand Down Expand Up @@ -287,6 +306,15 @@ extern NSString *const CHTCollectionElementKindSectionFooter;
*/
@property (nonatomic, assign) CHTCollectionViewWaterfallLayoutItemRenderDirection itemRenderDirection;

/**
* @brief The minimum height of the collection view's content.
* @discussion
* The minimum height of the collection view's content. This could be used to allow hidden headers with no content.
*
* Default: 0.f
*/
@property (nonatomic, assign) CGFloat minimumContentHeight;

/**
* @brief The calculated width of an item in the specified section.
* @discussion
Expand Down
60 changes: 43 additions & 17 deletions CHTCollectionViewWaterfallLayout.m
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
//

#import "CHTCollectionViewWaterfallLayout.h"
#import "tgmath.h"

NSString *const CHTCollectionElementKindSectionHeader = @"CHTCollectionElementKindSectionHeader";
NSString *const CHTCollectionElementKindSectionFooter = @"CHTCollectionElementKindSectionFooter";
Expand All @@ -30,7 +31,12 @@ @interface CHTCollectionViewWaterfallLayout ()
@implementation CHTCollectionViewWaterfallLayout

/// How many items to be union into a single rectangle
const NSInteger unionSize = 20;
static const NSInteger unionSize = 20;

static CGFloat CHTFloorCGFloat(CGFloat value) {
CGFloat scale = [UIScreen mainScreen].scale;
return floor(value * scale) / scale;
}

#pragma mark - Public Accessors
- (void)setColumnCount:(NSInteger)columnCount {
Expand Down Expand Up @@ -113,7 +119,13 @@ - (CGFloat)itemWidthInSectionAtIndex:(NSInteger)section {
}
CGFloat width = self.collectionView.frame.size.width - sectionInset.left - sectionInset.right;
NSInteger columnCount = [self columnCountForSection:section];
return floorf((width - (columnCount - 1) * self.minimumColumnSpacing) / columnCount);

CGFloat columnSpacing = self.minimumColumnSpacing;
if ([self.delegate respondsToSelector:@selector(collectionView:layout:minimumColumnSpacingForSectionAtIndex:)]) {
columnSpacing = [self.delegate collectionView:self.collectionView layout:self minimumColumnSpacingForSectionAtIndex:section];
}

return CHTFloorCGFloat((width - (columnCount - 1) * columnSpacing) / columnCount);
}

#pragma mark - Private Accessors
Expand Down Expand Up @@ -194,6 +206,13 @@ - (id)initWithCoder:(NSCoder *)aDecoder {
- (void)prepareLayout {
[super prepareLayout];

[self.headersAttribute removeAllObjects];
[self.footersAttribute removeAllObjects];
[self.unionRects removeAllObjects];
[self.columnHeights removeAllObjects];
[self.allItemAttributes removeAllObjects];
[self.sectionItemAttributes removeAllObjects];

NSInteger numberOfSections = [self.collectionView numberOfSections];
if (numberOfSections == 0) {
return;
Expand All @@ -205,13 +224,6 @@ - (void)prepareLayout {
// Initialize variables
NSInteger idx = 0;

[self.headersAttribute removeAllObjects];
[self.footersAttribute removeAllObjects];
[self.unionRects removeAllObjects];
[self.columnHeights removeAllObjects];
[self.allItemAttributes removeAllObjects];
[self.sectionItemAttributes removeAllObjects];

for (NSInteger section = 0; section < numberOfSections; section++) {
NSInteger columnCount = [self columnCountForSection:section];
NSMutableArray *sectionColumnHeights = [NSMutableArray arrayWithCapacity:columnCount];
Expand All @@ -235,6 +247,11 @@ - (void)prepareLayout {
minimumInteritemSpacing = self.minimumInteritemSpacing;
}

CGFloat columnSpacing = self.minimumColumnSpacing;
if ([self.delegate respondsToSelector:@selector(collectionView:layout:minimumColumnSpacingForSectionAtIndex:)]) {
columnSpacing = [self.delegate collectionView:self.collectionView layout:self minimumColumnSpacingForSectionAtIndex:section];
}

UIEdgeInsets sectionInset;
if ([self.delegate respondsToSelector:@selector(collectionView:layout:insetForSectionAtIndex:)]) {
sectionInset = [self.delegate collectionView:self.collectionView layout:self insetForSectionAtIndex:section];
Expand All @@ -244,7 +261,7 @@ - (void)prepareLayout {

CGFloat width = self.collectionView.frame.size.width - sectionInset.left - sectionInset.right;
NSInteger columnCount = [self columnCountForSection:section];
CGFloat itemWidth = floorf((width - (columnCount - 1) * self.minimumColumnSpacing) / columnCount);
CGFloat itemWidth = CHTFloorCGFloat((width - (columnCount - 1) * columnSpacing) / columnCount);

/*
* 2. Section header
Expand Down Expand Up @@ -293,12 +310,12 @@ - (void)prepareLayout {
for (idx = 0; idx < itemCount; idx++) {
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:idx inSection:section];
NSUInteger columnIndex = [self nextColumnIndexForItem:idx inSection:section];
CGFloat xOffset = sectionInset.left + (itemWidth + self.minimumColumnSpacing) * columnIndex;
CGFloat xOffset = sectionInset.left + (itemWidth + columnSpacing) * columnIndex;
CGFloat yOffset = [self.columnHeights[section][columnIndex] floatValue];
CGSize itemSize = [self.delegate collectionView:self.collectionView layout:self sizeForItemAtIndexPath:indexPath];
CGFloat itemHeight = 0;
if (itemSize.height > 0 && itemSize.width > 0) {
itemHeight = floorf(itemSize.height * itemWidth / itemSize.width);
itemHeight = CHTFloorCGFloat(itemSize.height * itemWidth / itemSize.width);
}

attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
Expand Down Expand Up @@ -354,11 +371,16 @@ - (void)prepareLayout {
idx = 0;
NSInteger itemCounts = [self.allItemAttributes count];
while (idx < itemCounts) {
CGRect rect1 = ((UICollectionViewLayoutAttributes *)self.allItemAttributes[idx]).frame;
idx = MIN(idx + unionSize, itemCounts) - 1;
CGRect rect2 = ((UICollectionViewLayoutAttributes *)self.allItemAttributes[idx]).frame;
[self.unionRects addObject:[NSValue valueWithCGRect:CGRectUnion(rect1, rect2)]];
idx++;
CGRect unionRect = ((UICollectionViewLayoutAttributes *)self.allItemAttributes[idx]).frame;
NSInteger rectEndIndex = MIN(idx + unionSize, itemCounts);

for (NSInteger i = idx + 1; i < rectEndIndex; i++) {
unionRect = CGRectUnion(unionRect, ((UICollectionViewLayoutAttributes *)self.allItemAttributes[i]).frame);
}

idx = rectEndIndex;

[self.unionRects addObject:[NSValue valueWithCGRect:unionRect]];
}
}

Expand All @@ -371,6 +393,10 @@ - (CGSize)collectionViewContentSize {
CGSize contentSize = self.collectionView.bounds.size;
contentSize.height = [[[self.columnHeights lastObject] firstObject] floatValue];

if (contentSize.height < self.minimumContentHeight) {
contentSize.height = self.minimumContentHeight;
}

return contentSize;
}

Expand Down
2 changes: 1 addition & 1 deletion CHTCollectionViewWaterfallLayout.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "CHTCollectionViewWaterfallLayout"
s.version = "0.8"
s.version = "0.9"
s.summary = "The waterfall (i.e., Pinterest-like) layout for UICollectionView."
s.homepage = "https://github.com/chiahsien/CHTCollectionViewWaterfallLayout"
s.screenshots = "https://raw.github.com/chiahsien/UICollectionViewWaterfallLayout/master/Screenshots/2-columns.png"
Expand Down
20 changes: 10 additions & 10 deletions CHTCollectionViewWaterfallLayout.swift
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,19 @@ import UIKit

@objc protocol CHTCollectionViewDelegateWaterfallLayout: UICollectionViewDelegate{

func collectionView (collectionView: UICollectionView!,layout collectionViewLayout: UICollectionViewLayout,
func collectionView (collectionView: UICollectionView,layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize

optional func colletionView (collectionView: UICollectionView!, layout collectionViewLayout: UICollectionViewLayout,
optional func colletionView (collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout,
heightForHeaderInSection section: NSInteger) -> CGFloat

optional func colletionView (collectionView: UICollectionView!, layout collectionViewLayout: UICollectionViewLayout,
optional func colletionView (collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout,
heightForFooterInSection section: NSInteger) -> CGFloat

optional func colletionView (collectionView: UICollectionView!, layout collectionViewLayout: UICollectionViewLayout,
optional func colletionView (collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout,
insetForSectionAtIndex section: NSInteger) -> UIEdgeInsets

optional func colletionView (collectionView: UICollectionView!, layout collectionViewLayout: UICollectionViewLayout,
optional func colletionView (collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout,
minimumInteritemSpacingForSectionAtIndex section: NSInteger) -> CGFloat
}

Expand Down Expand Up @@ -186,11 +186,11 @@ class CHTCollectionViewWaterfallLayout : UICollectionViewLayout{
self.headersAttributes.setObject(attributes, forKey: (section))
self.allItemAttributes.addObject(attributes)

top = CGRectGetMaxX(attributes.frame)
top = CGRectGetMaxY(attributes.frame)
}
top += sectionInset.top
for var idx = 0; idx < self.columnCount; idx++ {
self.columnHeights.setObject(top, atIndexedSubscript: idx)
self.columnHeights[idx]=top;
}

/*
Expand All @@ -216,7 +216,7 @@ class CHTCollectionViewWaterfallLayout : UICollectionViewLayout{
attributes.frame = CGRectMake(xOffset, CGFloat(yOffset), itemWidth, itemHeight)
itemAttributes.addObject(attributes)
self.allItemAttributes.addObject(attributes)
self.columnHeights.setObject(CGRectGetMaxY(attributes.frame) + minimumInteritemSpacing, atIndexedSubscript: columnIndex)
self.columnHeights[columnIndex]=CGRectGetMaxY(attributes.frame) + minimumInteritemSpacing;
}
self.sectionItemAttributes.addObject(itemAttributes)

Expand All @@ -242,7 +242,7 @@ class CHTCollectionViewWaterfallLayout : UICollectionViewLayout{
}

for var idx = 0; idx < self.columnCount; idx++ {
self.columnHeights.setObject(top, atIndexedSubscript: idx)
self.columnHeights[idx] = top
}
}

Expand Down Expand Up @@ -280,7 +280,7 @@ class CHTCollectionViewWaterfallLayout : UICollectionViewLayout{
return list.objectAtIndex(indexPath.item) as UICollectionViewLayoutAttributes
}

override func layoutAttributesForSupplementaryViewOfKind(elementKind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes!{
override func layoutAttributesForSupplementaryViewOfKind(elementKind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes{
var attribute = UICollectionViewLayoutAttributes()
if elementKind == CHTCollectionElementKindSectionHeader{
attribute = self.headersAttributes.objectForKey(indexPath.section) as UICollectionViewLayoutAttributes
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ Please let me know if your app is using this library. I'm glad to put your app o
F3PiX is a series of apps which gives you a concise, curated collection of pictures by professional (Dutch) photographers according to a specific theme. You can use the pictures freely for your own work.
* [GroupMe for iOS](https://itunes.apple.com/us/app/groupme/id392796698?mt=8)
GroupMe - A Home for All the Groups in Your Life.
* [Flickr](https://itunes.apple.com/us/app/id328407587)
Access and organize your photos from anywhere.

License
-------
Expand Down
Loading

0 comments on commit 7d8ee86

Please sign in to comment.