Skip to content
Browse files

Better use of threading to load huge collectionviews smoothyl during …

…live resize etc
  • Loading branch information...
1 parent d7a1dfd commit 5b9c8e92c28aded19236667ecd5c243629be6073 @pieteromvlee pieteromvlee committed Mar 2, 2011
View
2 BCCollectionView+Keyboard.m
@@ -3,7 +3,7 @@
#import "BCCollectionView+Keyboard.h"
#import "BCCollectionViewLayoutManager.h"
-#import "BCCollectionViewItemLayout.h"
+#import "BCCollectionViewLayoutItem.h"
@implementation BCCollectionView (BCCollectionView_Keyboard)
View
192 BCCollectionView.m
@@ -4,7 +4,7 @@
#import "BCCollectionView.h"
#import "BCGeometryExtensions.h"
#import "BCCollectionViewLayoutManager.h"
-#import "BCCollectionViewItemLayout.h"
+#import "BCCollectionViewLayoutItem.h"
#import "BCCollectionViewGroup.h"
@implementation BCCollectionView
@@ -43,6 +43,11 @@ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(N
else if ([keyPath isEqual:zoomValueObserverKey]) {
if ([self respondsToSelector:@selector(zoomValueDidChange)])
[self performSelector:@selector(zoomValueDidChange)];
+ } else if ([keyPath isEqualToString:@"isCollapsed"]) {
+ [self performSelector:@selector(viewDidResize)];
+ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^(void){
+ [self performSelector:@selector(scrollViewDidScroll:)];
+ });
} else
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
@@ -56,6 +61,9 @@ - (void)dealloc
[center removeObserver:self name:NSViewBoundsDidChangeNotification object:[[self enclosingScrollView] contentView]];
[center removeObserver:self name:NSViewFrameDidChangeNotification object:self];
+ for (BCCollectionViewGroup *group in groups)
+ [group removeObserver:self forKeyPath:@"isCollapsed"];
+
[layoutManager release];
[reusableViewControllers release];
[visibleViewControllers release];
@@ -179,25 +187,21 @@ - (NSUInteger)groupHeaderHeight
- (NSIndexSet *)indexesOfItemsInRect:(NSRect)aRect
{
- NSUInteger firstIndex = [layoutManager indexOfItemAtPoint:NSMakePoint(NSMinX(aRect), NSMinY(aRect))];
- NSUInteger lastIndex = [layoutManager indexOfItemAtPoint:NSMakePoint(NSMaxX(aRect), NSMaxY(aRect))];
-
- if (firstIndex == NSNotFound)
- firstIndex = 0;
-
- if (lastIndex == NSNotFound)
- lastIndex = [contentArray count]-1;
-
- NSMutableIndexSet *indexes = [NSMutableIndexSet indexSet];
- for (NSUInteger i=firstIndex; i<lastIndex+1; i++) {
- if (NSIntersectsRect(aRect, [layoutManager rectOfItemAtIndex:i]))
- [indexes addIndex:i];
- }
- return indexes;
+ NSArray *itemLayouts = [layoutManager itemLayouts];
+ NSIndexSet *visibleIndexes = [itemLayouts indexesOfObjectsWithOptions:NSEnumerationConcurrent passingTest:^BOOL(id itemLayout, NSUInteger idx, BOOL *stop) {
+ return NSIntersectsRect([itemLayout itemRect], aRect);
+ }];
+ return visibleIndexes;
}
- (NSIndexSet *)indexesOfItemContentRectsInRect:(NSRect)aRect
{
+ NSArray *itemLayouts = [layoutManager itemLayouts];
+ NSIndexSet *visibleIndexes = [itemLayouts indexesOfObjectsWithOptions:NSEnumerationConcurrent passingTest:^BOOL(id itemLayout, NSUInteger idx, BOOL *stop) {
+ return NSIntersectsRect([itemLayout itemRect], aRect);
+ }];
+ return visibleIndexes;
+
NSUInteger firstIndex = [layoutManager indexOfItemContentRectAtPoint:NSMakePoint(NSMinX(aRect), NSMinY(aRect))];
NSUInteger lastIndex = [layoutManager indexOfItemContentRectAtPoint:NSMakePoint(NSMaxX(aRect), NSMaxY(aRect))];
@@ -217,12 +221,7 @@ - (NSIndexSet *)indexesOfItemContentRectsInRect:(NSRect)aRect
- (NSRange)rangeOfVisibleItems
{
- NSArray *itemLayouts = [[layoutManager itemLayouts] copy];
- NSRect visibleRect = [self visibleRect];
- NSIndexSet *visibleIndexes = [itemLayouts indexesOfObjectsWithOptions:NSEnumerationConcurrent passingTest:^BOOL(id itemLayout, NSUInteger idx, BOOL *stop) {
- return NSIntersectsRect([itemLayout itemRect], visibleRect);
- }];
- [itemLayouts release];
+ NSIndexSet *visibleIndexes = [self indexesOfItemsInRect:[self visibleRect]];
return NSMakeRange([visibleIndexes firstIndex], [visibleIndexes lastIndex]-[visibleIndexes firstIndex]);
}
@@ -268,20 +267,26 @@ - (NSViewController *)viewControllerForItemAtIndex:(NSUInteger)index
#pragma mark Swapping ViewControllers in and out
+- (void)removeViewControllerForItemAtIndex:(NSUInteger)anIndex
+{
+ NSNumber *key = [NSNumber numberWithInteger:anIndex];
+ NSViewController *viewController = [visibleViewControllers objectForKey:key];
+ dispatch_async(dispatch_get_main_queue(), ^{
+ [[viewController view] removeFromSuperview];
+ });
+
+ [self delegateUpdateDeselectionForItemAtIndex:anIndex];
+ [self delegateViewControllerBecameInvisibleAtIndex:anIndex];
+
+ [reusableViewControllers addObject:viewController];
+ [visibleViewControllers removeObjectForKey:key];
+}
+
+
- (void)removeInvisibleViewControllers
{
[[self indexesOfInvisibleViewControllers] enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) {
- NSNumber *key = [NSNumber numberWithInteger:idx];
- NSViewController *viewController = [visibleViewControllers objectForKey:key];
- dispatch_async(dispatch_get_main_queue(), ^{
- [[viewController view] removeFromSuperview];
- });
-
- [self delegateUpdateDeselectionForItemAtIndex:idx];
- [self delegateViewControllerBecameInvisibleAtIndex:idx];
-
- [reusableViewControllers addObject:viewController];
- [visibleViewControllers removeObjectForKey:key];
+ [self removeViewControllerForItemAtIndex:idx];
}];
}
@@ -295,49 +300,61 @@ - (NSViewController *)emptyViewControllerForInsertion
return [delegate reusableViewControllerForCollectionView:self];
}
+- (void)addMissingViewControllerForItemAtIndex:(NSUInteger)anIndex withFrame:(NSRect)aRect
+{
+ NSViewController *viewController = [self emptyViewControllerForInsertion];
+ [visibleViewControllers setObject:viewController forKey:[NSNumber numberWithInteger:anIndex]];
+ [[viewController view] setFrame:aRect];
+ [[viewController view] setAutoresizingMask:NSViewMaxXMargin | NSViewMaxYMargin];
+
+ id itemToLoad = [contentArray objectAtIndex:anIndex];
+ [delegate collectionView:self willShowViewController:viewController forItem:itemToLoad];
+ [self addSubview:[viewController view]];
+ if ([selectionIndexes containsIndex:anIndex])
+ [self delegateUpdateSelectionForItemAtIndex:anIndex];
+}
+
+- (void)addMissingGroupHeaders
+{
+ if ([groups count] > 0) {
+ [groups enumerateObjectsUsingBlock:^(id group, NSUInteger idx, BOOL *stop) {
+ NSRect groupRect = NSMakeRect(0, NSMinY([layoutManager rectOfItemAtIndex:[group itemRange].location])-[self groupHeaderHeight],
+ NSWidth([self visibleRect]), [self groupHeaderHeight]);
+ BOOL groupShouldBeVisible = NSIntersectsRect(groupRect, [self visibleRect]);
+ NSViewController *groupViewController = [visibleGroupViewControllers objectForKey:[NSNumber numberWithInteger:idx]];
+ [[groupViewController view] setFrame:groupRect];
+ if (groupShouldBeVisible && !groupViewController) {
+ groupViewController = [delegate collectionView:self headerViewControllerForGroup:group];
+ [self addSubview:[groupViewController view]];
+ [visibleGroupViewControllers setObject:groupViewController forKey:[NSNumber numberWithInteger:idx]];
+ } else if (!groupShouldBeVisible && groupViewController) {
+ [[groupViewController view] removeFromSuperview];
+ [visibleGroupViewControllers removeObjectForKey:[NSNumber numberWithInteger:idx]];
+ }
+ }];
+ }
+}
+
- (void)addMissingViewControllersToView
{
dispatch_async(dispatch_get_main_queue(), ^{
[[NSIndexSet indexSetWithIndexesInRange:[self rangeOfVisibleItemsWithOverflow]] enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) {
- NSNumber *key = [NSNumber numberWithInteger:idx];
- if (![visibleViewControllers objectForKey:key]) {
- NSViewController *viewController = [self emptyViewControllerForInsertion];
- [visibleViewControllers setObject:viewController forKey:key];
- [[viewController view] setFrame:[layoutManager rectOfItemAtIndex:idx]];
- [[viewController view] setAutoresizingMask:NSViewMaxXMargin | NSViewMaxYMargin];
-
- id itemToLoad = [contentArray objectAtIndex:idx];
- [delegate collectionView:self willShowViewController:viewController forItem:itemToLoad];
- [self addSubview:[viewController view]];
- if ([selectionIndexes containsIndex:idx])
- [self delegateUpdateSelectionForItemAtIndex:idx];
+ if (![visibleViewControllers objectForKey:[NSNumber numberWithInteger:idx]]) {
+ [self addMissingViewControllerForItemAtIndex:idx withFrame:[layoutManager rectOfItemAtIndex:idx]];
}
}];
- if ([groups count] > 0) {
- [groups enumerateObjectsUsingBlock:^(id group, NSUInteger idx, BOOL *stop) {
- NSRect groupRect = NSMakeRect(0, NSMinY([layoutManager rectOfItemAtIndex:[group itemRange].location])-[self groupHeaderHeight],
- NSWidth([self visibleRect]), [self groupHeaderHeight]);
- BOOL groupShouldBeVisible = NSIntersectsRect(groupRect, [self visibleRect]);
- NSViewController *groupViewController = [visibleGroupViewControllers objectForKey:[NSNumber numberWithInteger:idx]];
- if (groupShouldBeVisible && !groupViewController) {
- groupViewController = [delegate collectionView:self headerViewControllerForGroup:group];
- [[groupViewController view] setFrame:groupRect];
- [self addSubview:[groupViewController view]];
- [visibleGroupViewControllers setObject:groupViewController forKey:[NSNumber numberWithInteger:idx]];
- } else if (!groupShouldBeVisible && groupViewController) {
- [[groupViewController view] removeFromSuperview];
- [visibleGroupViewControllers removeObjectForKey:[NSNumber numberWithInteger:idx]];
- }
- }];
- }
+ [self addMissingGroupHeaders];
});
}
- (void)moveViewControllersToProperPosition
{
- for (NSNumber *number in visibleViewControllers)
- [[[visibleViewControllers objectForKey:number] view] setFrame:[layoutManager rectOfItemAtIndex:[number integerValue]]];
+ for (NSNumber *number in visibleViewControllers) {
+ NSRect r = [layoutManager rectOfItemAtIndex:[number integerValue]];
+ if (!NSEqualRects(r, NSZeroRect))
+ [[[visibleViewControllers objectForKey:number] view] setFrame:r];
+ }
}
#pragma mark Selecting and Deselecting Items
@@ -384,12 +401,14 @@ - (void)selectItemsAtIndexes:(NSIndexSet *)indexes
- (void)deselectItemAtIndex:(NSUInteger)index
{
- [selectionIndexes removeIndex:index];
- if ([self shoulDrawSelections])
- [self setNeedsDisplayInRect:[layoutManager rectOfItemAtIndex:index]];
-
- [self delegateDidDeselectItemAtIndex:index];
- [self delegateUpdateDeselectionForItemAtIndex:index];
+ if (index < [contentArray count]) {
+ [selectionIndexes removeIndex:index];
+ if ([self shoulDrawSelections])
+ [self setNeedsDisplayInRect:[layoutManager rectOfItemAtIndex:index]];
+
+ [self delegateDidDeselectItemAtIndex:index];
+ [self delegateUpdateDeselectionForItemAtIndex:index];
+ }
}
- (void)deselectItemsAtIndexes:(NSIndexSet *)indexes
@@ -458,7 +477,9 @@ - (void)softReloadVisibleViewControllers
- (void)resizeFrameToFitContents
{
NSRect frame = [self frame];
- frame.size.height = MAX([self visibleRect].size.height, NSMaxY([layoutManager rectOfItemAtIndex:[contentArray count]-1]));
+ frame.size.height = [self visibleRect].size.height;
+ if ([contentArray count] > 0)
+ frame.size.height = MAX(frame.size.height, NSMaxY([layoutManager rectOfItemAtIndex:[contentArray count]-1]));
[self setFrame:frame];
}
@@ -474,9 +495,15 @@ - (void)reloadDataWithItems:(NSArray *)newContent groups:(NSArray *)newGroups em
if (!delegate)
return;
+ for (BCCollectionViewGroup *group in groups)
+ [group removeObserver:self forKeyPath:@"isCollapsed"];
+ for (BCCollectionViewGroup *group in newGroups)
+ [group addObserver:self forKeyPath:@"isCollapsed" options:0 context:NULL];
+
self.groups = newGroups;
self.contentArray = newContent;
- [layoutManager reloadWithCompletionBlock:^{
+
+ [layoutManager enumerateItems:NULL completionBlock:^{
[self resizeFrameToFitContents];
if (shouldEmptyCaches) {
@@ -521,12 +548,23 @@ - (void)scrollViewDidScroll:(NSNotification *)note
- (void)viewDidResize
{
- [layoutManager reloadWithCompletionBlock:^{
+ NSRect visibleRect = [self visibleRect];
+ [layoutManager enumerateItems:^(BCCollectionViewLayoutItem *layoutItem) {
+ BOOL shouldBeVisible = NSIntersectsRect([layoutItem itemRect], visibleRect);
+ if (shouldBeVisible) {
+ NSViewController *controller = [self viewControllerForItemAtIndex:[layoutItem itemIndex]];
+ if (controller)
+ [[controller view] setFrame:[layoutItem itemRect]];
+ else {
+ [self addMissingViewControllerForItemAtIndex:[layoutItem itemIndex] withFrame:[layoutItem itemRect]];
+ }
+ } else {
+ if ([self viewControllerForItemAtIndex:[layoutItem itemIndex]])
+ [self removeViewControllerForItemAtIndex:[layoutItem itemIndex]];
+ }
+ } completionBlock:^(void) {
[self resizeFrameToFitContents];
- dispatch_async(dispatch_get_main_queue(), ^{
- [self moveViewControllersToProperPosition];
- [self addMissingViewControllersToView];
- });
+ [self addMissingGroupHeaders];
}];
}
View
8 BCCollectionViewItemLayout.h → BCCollectionViewLayoutItem.h
@@ -3,12 +3,12 @@
#import <Foundation/Foundation.h>
-@interface BCCollectionViewItemLayout : NSObject
+@interface BCCollectionViewLayoutItem : NSObject
{
NSInteger rowIndex, columnIndex, itemIndex;
- NSRect itemRect;
+ NSRect itemRect, itemContentRect;
}
-@property NSInteger rowIndex, columnIndex, itemIndex;
-@property NSRect itemRect;
+@property (nonatomic) NSInteger rowIndex, columnIndex, itemIndex;
+@property (nonatomic) NSRect itemRect, itemContentRect;
+ (id)layoutItem;
@end
View
6 BCCollectionViewItemLayout.m → BCCollectionViewLayoutItem.m
@@ -1,10 +1,10 @@
// Created by Pieter Omvlee on 01/03/2011.
// Copyright 2011 Bohemian Coding. All rights reserved.
-#import "BCCollectionViewItemLayout.h"
+#import "BCCollectionViewLayoutItem.h"
-@implementation BCCollectionViewItemLayout
-@synthesize rowIndex, columnIndex, itemRect, itemIndex;
+@implementation BCCollectionViewLayoutItem
+@synthesize rowIndex, columnIndex, itemRect, itemIndex, itemContentRect;
+ (id)layoutItem
{
View
9 BCCollectionViewLayoutManager.h
@@ -2,22 +2,21 @@
// Copyright 2011 Bohemian Coding. All rights reserved.
#import <Foundation/Foundation.h>
+#import "BCCollectionViewLayoutOperation.h"
@class BCCollectionView;
@interface BCCollectionViewLayoutManager : NSObject
{
BCCollectionView *collectionView;
NSOperationQueue *queue;
- NSMutableArray *itemLayouts;
- NSInteger numberOfRows;
+ NSArray *itemLayouts;
}
-@property (readonly) NSArray *itemLayouts;
+@property (retain) NSArray *itemLayouts;
- (id)initWithCollectionView:(BCCollectionView *)collectionView; //assigned
-- (void)reloadWithCompletionBlock:(dispatch_block_t)completionBlock;
+- (void)enumerateItems:(BCCollectionViewLayoutOperationIterator)itemIterator completionBlock:(dispatch_block_t)completionBlock;
#pragma mark Primitives
-- (NSUInteger)numberOfRows;
- (NSUInteger)maximumNumberOfItemsPerRow;
- (NSSize)cellSize;
View
80 BCCollectionViewLayoutManager.m
@@ -4,7 +4,7 @@
#import "BCCollectionViewLayoutManager.h"
#import "BCCollectionView.h"
#import "BCCollectionViewGroup.h"
-#import "BCCollectionViewItemLayout.h"
+#import "BCCollectionViewLayoutItem.h"
@implementation BCCollectionViewLayoutManager
@synthesize itemLayouts;
@@ -14,66 +14,21 @@ - (id)initWithCollectionView:(BCCollectionView *)aCollectionView
self = [super init];
if (self) {
collectionView = aCollectionView;
- itemLayouts = [[NSMutableArray alloc] init];
- numberOfRows = -1;
queue = [[NSOperationQueue alloc] init];
[queue setMaxConcurrentOperationCount:1];
-
}
return self;
}
-- (void)reloadWithCompletionBlock:(dispatch_block_t)completionBlock
+- (void)enumerateItems:(BCCollectionViewLayoutOperationIterator)itemIterator completionBlock:(dispatch_block_t)completionBlock
{
- numberOfRows = 0;
[queue cancelAllOperations];
- [queue addOperationWithBlock:^{
- [itemLayouts removeAllObjects];
- NSInteger x = 0;
- NSInteger y = 0;
- NSUInteger colIndex = 0;
-
- NSEnumerator *groupEnum = [[collectionView groups] objectEnumerator];
- BCCollectionViewGroup *group = [groupEnum nextObject];
- NSSize cellSize = [self cellSize];
- NSUInteger count = [[collectionView contentArray] count];
- for (NSInteger i=0; i<count; i++) {
- if (group && [group itemRange].location == i) {
- if (x != 0) {
- numberOfRows++;
- colIndex = 0;
- y += cellSize.height;
- }
- y += [collectionView groupHeaderHeight];
- x = 0;
- }
- BCCollectionViewItemLayout *item = [BCCollectionViewItemLayout layoutItem];
- [item setItemIndex:i];
- if (![group isCollapsed]) {
- if (x + cellSize.width > NSMaxX([collectionView visibleRect])) {
- numberOfRows++;
- colIndex = 0;
- y += cellSize.height;
- x = 0;
- }
- [item setColumnIndex:colIndex];
- [item setItemRect:NSMakeRect(x, y, cellSize.width, cellSize.height)];
- x += cellSize.width;
- colIndex++;
- } else {
- [item setItemRect:NSMakeRect(x, y, 0, 0)];
- }
- [item setRowIndex:numberOfRows];
- [itemLayouts addObject:item];
-
- if ([group itemRange].location + [group itemRange].length-1 == i)
- group = [groupEnum nextObject];
- }
- numberOfRows = MAX(numberOfRows, [[collectionView groups] count]);
- if ([[collectionView contentArray] count] > 0 && numberOfRows == -1)
- numberOfRows = 1;
- dispatch_async(dispatch_get_main_queue(), completionBlock);
- }];
+
+ BCCollectionViewLayoutOperation *operation = [[BCCollectionViewLayoutOperation alloc] init];
+ [operation setCollectionView:collectionView];
+ [operation setLayoutCallBack:itemIterator];
+ [operation setCompletionBlock:completionBlock];
+ [queue addOperation:[operation autorelease]];
}
- (void)dealloc
@@ -86,11 +41,6 @@ - (void)dealloc
#pragma mark -
#pragma mark Primitives
-- (NSUInteger)numberOfRows
-{
- return numberOfRows;
-}
-
- (NSUInteger)maximumNumberOfItemsPerRow
{
return MAX(1, [collectionView frame].size.width/[self cellSize].width);
@@ -106,7 +56,7 @@ - (NSSize)cellSize
- (NSPoint)rowAndColumnPositionOfItemAtIndex:(NSUInteger)anIndex
{
- BCCollectionViewItemLayout *itemLayout = [itemLayouts objectAtIndex:anIndex];
+ BCCollectionViewLayoutItem *itemLayout = [itemLayouts objectAtIndex:anIndex];
return NSMakePoint(itemLayout.columnIndex, itemLayout.rowIndex);
}
@@ -154,16 +104,14 @@ - (NSRect)rectOfItemAtIndex:(NSUInteger)anIndex
if (anIndex < [itemLayouts count])
return [[itemLayouts objectAtIndex:anIndex] itemRect];
else
- return NSMakeRect(0, 0, [self cellSize].width, [self cellSize].height);
+ return NSZeroRect;
}
- (NSRect)contentRectOfItemAtIndex:(NSUInteger)anIndex
{
- NSRect rect = [self rectOfItemAtIndex:anIndex];
- if ([[collectionView delegate] respondsToSelector:@selector(insetMarginForSelectingItemsInCollectionView:)]) {
- NSSize inset = [[collectionView delegate] insetMarginForSelectingItemsInCollectionView:collectionView];
- return NSInsetRect(rect, inset.width, inset.height);
- } else
- return rect;
+ if (anIndex < [itemLayouts count])
+ return [[itemLayouts objectAtIndex:anIndex] itemContentRect];
+ else
+ return NSZeroRect;
}
@end
View
18 BCCollectionViewLayoutOperation.h
@@ -0,0 +1,18 @@
+// Created by Pieter Omvlee on 02/03/2011.
+// Copyright 2011 Bohemian Coding. All rights reserved.
+
+#import <Foundation/Foundation.h>
+
+@class BCCollectionView, BCCollectionViewLayoutItem;
+
+typedef void(^BCCollectionViewLayoutOperationIterator)(BCCollectionViewLayoutItem *layoutItem);
+
+@interface BCCollectionViewLayoutOperation : NSOperation
+{
+ BCCollectionViewLayoutOperationIterator layoutCallBack;
+ BCCollectionView *collectionView;
+}
+@property (copy) BCCollectionViewLayoutOperationIterator layoutCallBack;
+@property (assign) BCCollectionView *collectionView;
+
+@end
View
92 BCCollectionViewLayoutOperation.m
@@ -0,0 +1,92 @@
+// Created by Pieter Omvlee on 02/03/2011.
+// Copyright 2011 Bohemian Coding. All rights reserved.
+
+#import "BCCollectionViewLayoutOperation.h"
+#import "BCCollectionView.h"
+#import "BCCollectionViewLayoutItem.h"
+#import "BCCollectionViewGroup.h"
+#import "BCCollectionViewLayoutManager.h"
+
+@implementation BCCollectionViewLayoutOperation
+@synthesize layoutCallBack, collectionView;
+
+- (void)main
+{
+ NSInteger numberOfRows = 0;
+
+ NSInteger x = 0;
+ NSInteger y = 0;
+ NSUInteger colIndex = 0;
+
+ NSSize cellSize = [collectionView cellSize];
+ NSSize inset = NSZeroSize;
+ if ([[collectionView delegate] respondsToSelector:@selector(insetMarginForSelectingItemsInCollectionView:)])
+ inset = [[collectionView delegate] insetMarginForSelectingItemsInCollectionView:collectionView];
+
+ NSMutableArray *newLayouts = [NSMutableArray array];
+ NSEnumerator *groupEnum = [[collectionView groups] objectEnumerator];
+ BCCollectionViewGroup *group = [groupEnum nextObject];
+
+ NSUInteger count = [[collectionView contentArray] count];
+ for (NSInteger i=0; i<count; i++) {
+ if ([self isCancelled])
+ return;
+
+ if (group && [group itemRange].location == i) {
+ if (x != 0) {
+ numberOfRows++;
+ colIndex = 0;
+ y += cellSize.height;
+ }
+ y += [collectionView groupHeaderHeight];
+ x = 0;
+ }
+ BCCollectionViewLayoutItem *item = [BCCollectionViewLayoutItem layoutItem];
+ [item setItemIndex:i];
+ if (![group isCollapsed]) {
+ if (x + cellSize.width > NSMaxX([collectionView visibleRect])) {
+ numberOfRows++;
+ colIndex = 0;
+ y += cellSize.height;
+ x = 0;
+ }
+ [item setColumnIndex:colIndex];
+ [item setItemRect:NSMakeRect(x, y, cellSize.width, cellSize.height)];
+ x += cellSize.width;
+ colIndex++;
+ } else {
+ [item setItemRect:NSMakeRect(-cellSize.width*2, y, cellSize.width, cellSize.height)];
+ }
+ [item setItemContentRect:NSInsetRect([item itemRect], inset.width, inset.height)];
+ [item setRowIndex:numberOfRows];
+ [newLayouts addObject:item];
+
+ if ([self isCancelled])
+ return;
+
+ if (layoutCallBack != nil)
+ dispatch_async(dispatch_get_main_queue(), ^{
+ layoutCallBack(item);
+ });
+
+ if ([group itemRange].location + [group itemRange].length-1 == i)
+ group = [groupEnum nextObject];
+ }
+ numberOfRows = MAX(numberOfRows, [[collectionView groups] count]);
+ if ([[collectionView contentArray] count] > 0 && numberOfRows == -1)
+ numberOfRows = 1;
+
+ if (![self isCancelled]) {
+ dispatch_async(dispatch_get_main_queue(), ^{
+ [[collectionView layoutManager] setItemLayouts:newLayouts];
+ });
+ }
+}
+
+- (void)dealloc
+{
+ [layoutCallBack release];
+ [super dealloc];
+}
+
+@end

0 comments on commit 5b9c8e9

Please sign in to comment.
Something went wrong with that request. Please try again.