Skip to content

Commit

Permalink
Merge branch 'release/0.9.3'
Browse files Browse the repository at this point in the history
  • Loading branch information
chiahsien committed Apr 7, 2016
2 parents 19fc59e + 0457513 commit dc97d8b
Show file tree
Hide file tree
Showing 57 changed files with 227 additions and 984 deletions.
14 changes: 12 additions & 2 deletions CHTCollectionViewWaterfallLayout.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,17 @@ Pod::Spec.new do |s|
s.license = 'MIT'
s.author = { "Nelson" => "chiahsien@gmail.com" }
s.source = { :git => "https://github.com/chiahsien/CHTCollectionViewWaterfallLayout.git", :tag => "#{s.version}" }
s.platform = :ios, '6.0'
s.source_files = '*.{h,m}'
s.ios.deployment_target = '6.0'
s.tvos.deployment_target = '9.0'
s.requires_arc = true

s.default_subspec = 'ObjC'

s.subspec 'ObjC' do |ss|
ss.source_files = '*.{h,m}'
end

s.subspec 'Swift' do |ss|
ss.source_files = '*.swift'
end
end
158 changes: 92 additions & 66 deletions CHTCollectionViewWaterfallLayout.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ import UIKit

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

optional func collectionView (collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout,
columnCountForSection section: NSInteger) -> NSInteger
}

enum CHTCollectionViewWaterfallLayoutItemRenderDirection : NSInteger{
Expand Down Expand Up @@ -108,9 +111,17 @@ class CHTCollectionViewWaterfallLayout : UICollectionViewLayout{
super.init()
}

required init(coder aDecoder: NSCoder) {
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

func columnCountForSection (section : NSInteger) -> NSInteger {
if let columnCount = self.delegate?.collectionView?(self.collectionView!, layout: self, columnCountForSection: section){
return columnCount
}else{
return self.columnCount
}
}

func itemWidthInSectionAtIndex (section : NSInteger) -> CGFloat {
var insets : UIEdgeInsets
Expand All @@ -119,9 +130,10 @@ class CHTCollectionViewWaterfallLayout : UICollectionViewLayout{
}else{
insets = self.sectionInset
}
let width:CGFloat = self.collectionView!.bounds.size.width - sectionInset.left-sectionInset.right
let spaceColumCount:CGFloat = CGFloat(self.columnCount-1)
return floor((width - (spaceColumCount*self.minimumColumnSpacing)) / CGFloat(self.columnCount))
let width:CGFloat = self.collectionView!.bounds.size.width - insets.left-insets.right
let columnCount = self.columnCountForSection(section)
let spaceColumCount:CGFloat = CGFloat(columnCount-1)
return floor((width - (spaceColumCount*self.minimumColumnSpacing)) / CGFloat(columnCount))
}

override func prepareLayout(){
Expand All @@ -139,16 +151,19 @@ class CHTCollectionViewWaterfallLayout : UICollectionViewLayout{
self.allItemAttributes.removeAllObjects()
self.sectionItemAttributes.removeAllObjects()

var idx = 0
while idx<self.columnCount{
self.columnHeights.addObject(0)
idx++
for section in 0 ..< numberOfSections {
let columnCount = self.columnCountForSection(section)
let sectionColumnHeights = NSMutableArray(capacity: columnCount)
for idx in 0 ..< columnCount {
sectionColumnHeights.addObject(idx)
}
self.columnHeights.addObject(sectionColumnHeights)
}

var top : CGFloat = 0.0
var attributes = UICollectionViewLayoutAttributes()

for var section = 0; section < numberOfSections; ++section{
for section in 0 ..< numberOfSections {
/*
* 1. Get section-specific metrics (minimumInteritemSpacing, sectionInset)
*/
Expand All @@ -166,9 +181,10 @@ class CHTCollectionViewWaterfallLayout : UICollectionViewLayout{
sectionInsets = self.sectionInset
}

let width = self.collectionView!.bounds.size.width - sectionInset.left - sectionInset.right
let spaceColumCount = CGFloat(self.columnCount-1)
let itemWidth = floor((width - (spaceColumCount*self.minimumColumnSpacing)) / CGFloat(self.columnCount))
let width = self.collectionView!.bounds.size.width - sectionInsets.left - sectionInsets.right
let columnCount = self.columnCountForSection(section)
let spaceColumCount = CGFloat(columnCount-1)
let itemWidth = floor((width - (spaceColumCount*self.minimumColumnSpacing)) / CGFloat(columnCount))

/*
* 2. Section header
Expand All @@ -188,9 +204,11 @@ class CHTCollectionViewWaterfallLayout : UICollectionViewLayout{

top = CGRectGetMaxY(attributes.frame)
}
top += sectionInset.top
for var idx = 0; idx < self.columnCount; idx++ {
self.columnHeights[idx]=top;
top += sectionInsets.top
for idx in 0 ..< columnCount {
if let sectionColumnHeights = self.columnHeights[section] as? NSMutableArray {
sectionColumnHeights[idx]=top
}
}

/*
Expand All @@ -200,12 +218,12 @@ class CHTCollectionViewWaterfallLayout : UICollectionViewLayout{
let itemAttributes = NSMutableArray(capacity: itemCount)

// Item will be put into shortest column.
for var idx = 0; idx < itemCount; idx++ {
for idx in 0 ..< itemCount {
let indexPath = NSIndexPath(forItem: idx, inSection: section)

let columnIndex = self.nextColumnIndexForItem(idx)
let xOffset = sectionInset.left + (itemWidth + self.minimumColumnSpacing) * CGFloat(columnIndex)
let yOffset = self.columnHeights.objectAtIndex(columnIndex).doubleValue
let columnIndex = self.nextColumnIndexForItem(idx, section: section)
let xOffset = sectionInsets.left + (itemWidth + self.minimumColumnSpacing) * CGFloat(columnIndex)
let yOffset = self.columnHeights[section].objectAtIndex(columnIndex).doubleValue
let itemSize = self.delegate?.collectionView(self.collectionView!, layout: self, sizeForItemAtIndexPath: indexPath)
var itemHeight : CGFloat = 0.0
if itemSize?.height > 0 && itemSize?.width > 0 {
Expand All @@ -216,16 +234,19 @@ class CHTCollectionViewWaterfallLayout : UICollectionViewLayout{
attributes.frame = CGRectMake(xOffset, CGFloat(yOffset), itemWidth, itemHeight)
itemAttributes.addObject(attributes)
self.allItemAttributes.addObject(attributes)
self.columnHeights[columnIndex]=CGRectGetMaxY(attributes.frame) + minimumInteritemSpacing;

if let sectionColumnHeights = self.columnHeights[section] as? NSMutableArray {
sectionColumnHeights[columnIndex]=CGRectGetMaxY(attributes.frame) + minimumInteritemSpacing
}
}
self.sectionItemAttributes.addObject(itemAttributes)

/*
* 4. Section footer
*/
var footerHeight : CGFloat = 0.0
let columnIndex = self.longestColumnIndex()
top = CGFloat(self.columnHeights.objectAtIndex(columnIndex).floatValue) - minimumInteritemSpacing + sectionInset.bottom
let columnIndex = self.longestColumnIndexInSection(section)
top = CGFloat(self.columnHeights[section].objectAtIndex(columnIndex).floatValue) - minimumInteritemSpacing + sectionInsets.bottom

if let height = self.delegate?.collectionView?(self.collectionView!, layout: self, heightForFooterInSection: section){
footerHeight = height
Expand All @@ -241,84 +262,90 @@ class CHTCollectionViewWaterfallLayout : UICollectionViewLayout{
top = CGRectGetMaxY(attributes.frame)
}

for var idx = 0; idx < self.columnCount; idx++ {
self.columnHeights[idx] = top
for idx in 0 ..< columnCount {
if let sectionColumnHeights = self.columnHeights[section] as? NSMutableArray {
sectionColumnHeights[idx]=top
}
}
}

idx = 0;
var idx = 0
let itemCounts = self.allItemAttributes.count
while(idx < itemCounts){
var rect1 = self.allItemAttributes.objectAtIndex(idx).frame as CGRect
let rect1 = self.allItemAttributes.objectAtIndex(idx).frame as CGRect
idx = min(idx + unionSize, itemCounts) - 1
var rect2 = self.allItemAttributes.objectAtIndex(idx).frame as CGRect
let rect2 = self.allItemAttributes.objectAtIndex(idx).frame as CGRect
self.unionRects.addObject(NSValue(CGRect:CGRectUnion(rect1,rect2)))
idx++
idx += 1
}
}

override func collectionViewContentSize() -> CGSize{
var numberOfSections = self.collectionView!.numberOfSections()
let numberOfSections = self.collectionView!.numberOfSections()
if numberOfSections == 0{
return CGSizeZero
}

var contentSize = self.collectionView!.bounds.size as CGSize
let height = self.columnHeights.objectAtIndex(0) as NSNumber
let height = self.columnHeights.lastObject!.firstObject as! NSNumber
contentSize.height = CGFloat(height.doubleValue)
return contentSize
return contentSize
}
override func layoutAttributesForItemAtIndexPath(indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes!{
if indexPath.section >= self.sectionItemAttributes.count{

override func layoutAttributesForItemAtIndexPath(indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes? {
if indexPath.section >= self.sectionItemAttributes.count {
return nil
}
if indexPath.item >= self.sectionItemAttributes.objectAtIndex(indexPath.section).count{
let list = self.sectionItemAttributes.objectAtIndex(indexPath.section) as! NSArray

if indexPath.item >= list.count {
return nil;
}
var list = self.sectionItemAttributes.objectAtIndex(indexPath.section) as NSArray
return list.objectAtIndex(indexPath.item) as UICollectionViewLayoutAttributes
return list.objectAtIndex(indexPath.item) as? UICollectionViewLayoutAttributes
}

override func layoutAttributesForSupplementaryViewOfKind(elementKind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes{
var attribute = UICollectionViewLayoutAttributes()
if elementKind == CHTCollectionElementKindSectionHeader{
attribute = self.headersAttributes.objectForKey(indexPath.section) as UICollectionViewLayoutAttributes
attribute = self.headersAttributes.objectForKey(indexPath.section) as! UICollectionViewLayoutAttributes
}else if elementKind == CHTCollectionElementKindSectionFooter{
attribute = self.footersAttributes.objectForKey(indexPath.section) as UICollectionViewLayoutAttributes
attribute = self.footersAttributes.objectForKey(indexPath.section) as! UICollectionViewLayoutAttributes
}
return attribute
}

override func layoutAttributesForElementsInRect (rect : CGRect) -> [AnyObject] {
var i = 0

override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
var begin = 0, end = self.unionRects.count
var attrs = NSMutableArray()
let attrs = NSMutableArray()

for var i = 0; i < end; i++ {
if CGRectIntersectsRect(rect, self.unionRects.objectAtIndex(i).CGRectValue()){
begin = i * unionSize;
break
for i in 0 ..< end {
if let unionRect = self.unionRects.objectAtIndex(i) as? NSValue {
if CGRectIntersectsRect(rect, unionRect.CGRectValue()) {
begin = i * unionSize;
break
}
}
}
for var i = self.unionRects.count - 1; i>=0; i-- {
if CGRectIntersectsRect(rect, self.unionRects.objectAtIndex(i).CGRectValue()){
end = min((i+1)*unionSize,self.allItemAttributes.count)
break
for i in (0 ..< self.unionRects.count).reverse() {
if let unionRect = self.unionRects.objectAtIndex(i) as? NSValue {
if CGRectIntersectsRect(rect, unionRect.CGRectValue()){
end = min((i+1)*unionSize,self.allItemAttributes.count)
break
}
}
}
for var i = begin; i < end; i++ {
var attr = self.allItemAttributes.objectAtIndex(i) as UICollectionViewLayoutAttributes
for i in begin ..< end {
let attr = self.allItemAttributes.objectAtIndex(i) as! UICollectionViewLayoutAttributes
if CGRectIntersectsRect(rect, attr.frame) {
attrs.addObject(attr)
}
}

return NSArray(array: attrs)
return NSArray(array: attrs) as? [UICollectionViewLayoutAttributes]
}

override func shouldInvalidateLayoutForBoundsChange (newBounds : CGRect) -> Bool {
var oldBounds = self.collectionView!.bounds
let oldBounds = self.collectionView!.bounds
if CGRectGetWidth(newBounds) != CGRectGetWidth(oldBounds){
return true
}
Expand All @@ -331,11 +358,11 @@ class CHTCollectionViewWaterfallLayout : UICollectionViewLayout{
*
* @return index for the shortest column
*/
func shortestColumnIndex () -> NSInteger {
func shortestColumnIndexInSection (section: NSInteger) -> NSInteger {
var index = 0
var shorestHeight = MAXFLOAT

self.columnHeights.enumerateObjectsUsingBlock({(object : AnyObject!, idx : NSInteger,pointer :UnsafeMutablePointer<ObjCBool>) in
self.columnHeights[section].enumerateObjectsUsingBlock({(object : AnyObject!, idx : NSInteger,pointer :UnsafeMutablePointer<ObjCBool>) in
let height = object.floatValue
if (height<shorestHeight){
shorestHeight = height
Expand All @@ -351,11 +378,11 @@ class CHTCollectionViewWaterfallLayout : UICollectionViewLayout{
* @return index for the longest column
*/

func longestColumnIndex () -> NSInteger {
func longestColumnIndexInSection (section: NSInteger) -> NSInteger {
var index = 0
var longestHeight:CGFloat = 0.0

self.columnHeights.enumerateObjectsUsingBlock({(object : AnyObject!, idx : NSInteger,pointer :UnsafeMutablePointer<ObjCBool>) in
self.columnHeights[section].enumerateObjectsUsingBlock({(object : AnyObject!, idx : NSInteger,pointer :UnsafeMutablePointer<ObjCBool>) in
let height = CGFloat(object.floatValue)
if (height > longestHeight){
longestHeight = height
Expand All @@ -370,17 +397,16 @@ class CHTCollectionViewWaterfallLayout : UICollectionViewLayout{
*
* @return index for the next column
*/
func nextColumnIndexForItem (item : NSInteger) -> Int {
func nextColumnIndexForItem (item : NSInteger, section: NSInteger) -> Int {
var index = 0
let columnCount = self.columnCountForSection(section)
switch (self.itemRenderDirection){
case .CHTCollectionViewWaterfallLayoutItemRenderDirectionShortestFirst :
index = self.shortestColumnIndex()
index = self.shortestColumnIndexInSection(section)
case .CHTCollectionViewWaterfallLayoutItemRenderDirectionLeftToRight :
index = (item%self.columnCount)
index = (item%columnCount)
case .CHTCollectionViewWaterfallLayoutItemRenderDirectionRightToLeft:
index = (self.columnCount - 1) - (item % self.columnCount);
default:
index = self.shortestColumnIndex()
index = (columnCount - 1) - (item % columnCount);
}
return index
}
Expand Down
57 changes: 0 additions & 57 deletions Demo/Demo/CHTCollectionViewWaterfallCell.m

This file was deleted.

Loading

0 comments on commit dc97d8b

Please sign in to comment.