Permalink
Browse files

Initial reuse strategy

  • Loading branch information...
soffes committed Mar 15, 2011
1 parent 35a54cc commit a12ab590d1a61d97961b473f3be0c3bb8659fe38
View
@@ -8,7 +8,7 @@ If you're using this in your project, I'd love to hear about it! [Send me an ema
### Views
-* [SSCollectionView][] - simple collection view modeled after UITableView and NSCollectionView (*Note: currently unstable. Use the version in the stable branch unless you're feeling adventurous.*)
+* [SSCollectionView][] - simple collection view modeled after UITableView and NSCollectionView
* [SSGradientView][] - easily create gradients with optional borders and insets
* [SSHUDView][] - simple heads-up display
* [SSLabel][] - ever wanted to align your text to the top or the bottom
@@ -46,11 +46,14 @@ - (SSCollectionViewItem *)collectionView:(SSCollectionView *)aCollectionView ite
SSCollectionViewItem *item = [aCollectionView dequeueReusableItemWithIdentifier:itemIdentifier];
if (item == nil) {
+ NSLog(@"Allocating");
item = [[[SSCollectionViewItem alloc] initWithStyle:SSCollectionViewItemStyleDefault reuseIdentifier:itemIdentifier] autorelease];
// Customize item for demo
item.textLabel.backgroundColor = [UIColor colorWithWhite:0.9f alpha:1.0f];
item.textLabel.frame = CGRectMake(0.0f, 0.0f, 80.0f, 80.0f);
+ } else {
+ NSLog(@"Reusing");
}
item.textLabel.text = [NSString stringWithFormat:@"%i", indexPath.row];
@@ -76,6 +76,8 @@
B24E9E80121DC29A0085F81E /* UIViewController+SSToolkitAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = B24E9E42121DC29A0085F81E /* UIViewController+SSToolkitAdditions.m */; };
B267D3451226CE0400B66519 /* SSCollectionViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = B267D3431226CE0400B66519 /* SSCollectionViewController.h */; };
B267D3461226CE0400B66519 /* SSCollectionViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B267D3441226CE0400B66519 /* SSCollectionViewController.m */; };
+ B2721B9E132F131100D762FD /* SSCollectionViewItemInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = B2721B9D132F131100D762FD /* SSCollectionViewItemInternal.h */; };
+ B2721BA0132F136C00D762FD /* SSCollectionViewInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = B2721B9F132F136C00D762FD /* SSCollectionViewInternal.h */; };
B279539912FC67E300FFE28D /* UIScreen+SSToolkitAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = B279539712FC67E300FFE28D /* UIScreen+SSToolkitAdditions.h */; };
B279539A12FC67E300FFE28D /* UIScreen+SSToolkitAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = B279539812FC67E300FFE28D /* UIScreen+SSToolkitAdditions.m */; };
B279539E12FC6C6F00FFE28D /* SSRatingPickerScrollView.h in Headers */ = {isa = PBXBuildFile; fileRef = B279539C12FC6C6F00FFE28D /* SSRatingPickerScrollView.h */; };
@@ -181,6 +183,8 @@
B24E9E42121DC29A0085F81E /* UIViewController+SSToolkitAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIViewController+SSToolkitAdditions.m"; sourceTree = "<group>"; };
B267D3431226CE0400B66519 /* SSCollectionViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SSCollectionViewController.h; sourceTree = "<group>"; };
B267D3441226CE0400B66519 /* SSCollectionViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SSCollectionViewController.m; sourceTree = "<group>"; };
+ B2721B9D132F131100D762FD /* SSCollectionViewItemInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SSCollectionViewItemInternal.h; sourceTree = "<group>"; };
+ B2721B9F132F136C00D762FD /* SSCollectionViewInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SSCollectionViewInternal.h; sourceTree = "<group>"; };
B279539712FC67E300FFE28D /* UIScreen+SSToolkitAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIScreen+SSToolkitAdditions.h"; sourceTree = "<group>"; };
B279539812FC67E300FFE28D /* UIScreen+SSToolkitAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIScreen+SSToolkitAdditions.m"; sourceTree = "<group>"; };
B279539C12FC6C6F00FFE28D /* SSRatingPickerScrollView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SSRatingPickerScrollView.h; sourceTree = "<group>"; };
@@ -435,8 +439,10 @@
B2E241511301C71400F7DC3B /* SSAddressBarTextFieldBackgroundView.m */,
B2E241521301C71400F7DC3B /* SSAddressBarTextFieldBackgroundViewInnerView.h */,
B2E241531301C71400F7DC3B /* SSAddressBarTextFieldBackgroundViewInnerView.m */,
+ B2721B9F132F136C00D762FD /* SSCollectionViewInternal.h */,
B2ABC6901329D14300521D20 /* SSCollectionViewTableViewCell.h */,
B2ABC6911329D14300521D20 /* SSCollectionViewTableViewCell.m */,
+ B2721B9D132F131100D762FD /* SSCollectionViewItemInternal.h */,
B279539C12FC6C6F00FFE28D /* SSRatingPickerScrollView.h */,
B279539D12FC6C6F00FFE28D /* SSRatingPickerScrollView.m */,
);
@@ -510,6 +516,8 @@
B2E241561301C71400F7DC3B /* SSAddressBarTextFieldBackgroundView.h in Headers */,
B2E241581301C71400F7DC3B /* SSAddressBarTextFieldBackgroundViewInnerView.h in Headers */,
B2ABC6921329D14300521D20 /* SSCollectionViewTableViewCell.h in Headers */,
+ B2721B9E132F131100D762FD /* SSCollectionViewItemInternal.h in Headers */,
+ B2721BA0132F136C00D762FD /* SSCollectionViewInternal.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -33,12 +33,10 @@
CGFloat _minimumColumnSpacing;
CGFloat _rowSpacing;
BOOL _allowsSelection;
+ NSMutableDictionary *_reuseableItems;
+ NSMutableSet *_visibleItemPointers;
UITableView *_tableView;
-
- UIView *_backgroundView;
- UIView *_backgroundHeaderView;
- UIView *_backgroundFooterView;
}
/**
@@ -66,9 +64,6 @@
*/
@property (nonatomic, retain) UIView *backgroundView;
-@property (nonatomic, retain) UIView *backgroundHeaderView;
-@property (nonatomic, retain) UIView *backgroundFooterView;
-
/**
@brief A Boolean value that determines whether selecting items is enabled.
@@ -7,7 +7,9 @@
//
#import "SSCollectionView.h"
+#import "SSCollectionViewInternal.h"
#import "SSCollectionViewItem.h"
+#import "SSCollectionViewItemInternal.h"
#import "SSCollectionViewTableViewCell.h"
#import "SSDrawingMacros.h"
#import "UIView+SSToolkitAdditions.h"
@@ -16,8 +18,6 @@ @interface SSCollectionView (PrivateMethods)
- (CGSize)_itemSizeForSection:(NSInteger)section;
- (NSInteger)_numberOfItemsInSection:(NSInteger)section;
- (NSArray *)_itemsForRowIndexPath:(NSIndexPath *)rowIndexPath;
-- (NSIndexPath *)_rowIndexPathForItemIndexPath:(NSIndexPath *)itemIndexPath;
-- (NSIndexPath *)_deepRowIndexPathForItemIndexPath:(NSIndexPath *)itemIndexPath;
@end
@implementation SSCollectionView
@@ -26,9 +26,6 @@ @implementation SSCollectionView
@synthesize delegate = _delegate;
@synthesize minimumColumnSpacing = _minimumColumnSpacing;
@synthesize rowSpacing = _rowSpacing;
-@synthesize backgroundView = _backgroundView;
-@synthesize backgroundHeaderView = _backgroundHeaderView;
-@synthesize backgroundFooterView = _backgroundFooterView;
@synthesize allowsSelection = _allowsSelection;
#pragma mark NSObject
@@ -37,14 +34,29 @@ - (void)dealloc {
self.dataSource = nil;
self.delegate = nil;
+ // Remove references to visible items
+ for (NSValue *value in _visibleItemPointers) {
+ [(SSCollectionViewItem *)[value pointerValue] setCollectionView:nil];
+ }
+ [_visibleItemPointers removeAllObjects];
+ [_visibleItemPointers release];
+ _visibleItemPointers = nil;
+
+ // Remove all reuseable items
+ for (NSString *key in _reuseableItems) {
+ NSArray *items = [_reuseableItems objectForKey:key];
+ for (SSCollectionViewItem *item in items) {
+ item.collectionView = nil;
+ }
+ [_reuseableItems removeObjectForKey:key];
+ }
+ [_reuseableItems release];
+ _reuseableItems = nil;
+
_tableView.dataSource = nil;
_tableView.delegate = nil;
[_tableView release];
- self.backgroundView = nil;
- self.backgroundHeaderView = nil;
- self.backgroundFooterView = nil;
-
[super dealloc];
}
@@ -59,6 +71,8 @@ - (id)initWithFrame:(CGRect)frame {
_minimumColumnSpacing = 10.0f;
_rowSpacing = 20.0f;
_allowsSelection = YES;
+ _reuseableItems = [[NSMutableDictionary alloc] init];
+ _visibleItemPointers = [[NSMutableSet alloc] init];
_tableView = [[UITableView alloc] initWithFrame:CGRectSetZeroOrigin(frame)];
_tableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
@@ -79,8 +93,20 @@ - (void)reloadData {
- (SSCollectionViewItem *)dequeueReusableItemWithIdentifier:(NSString *)identifier {
- // TODO: Store items and reuse
- return nil;
+ if (!identifier) {
+ return nil;
+ }
+
+ NSMutableArray *items = [_reuseableItems objectForKey:identifier];
+ if (!items || [items count] == 0) {
+ return nil;
+ }
+
+ SSCollectionViewItem *item = [items lastObject];
+ [items removeLastObject];
+
+ [item prepareForReuse];
+ return item;
}
@@ -113,6 +139,23 @@ - (void)reloadItemAtIndexPaths:(NSIndexPath *)indexPaths {
#pragma mark Private Methods
+- (void)_reuseItem:(SSCollectionViewItem *)item {
+ NSMutableArray *items = [_reuseableItems objectForKey:item.reuseIdentifier];
+ if (!items) {
+ [_reuseableItems setObject:[NSMutableArray array] forKey:item.reuseIdentifier];
+ }
+
+ [items addObject:item];
+}
+
+
+- (void)_itemsWillDisappear:(NSArray *)items {
+ for (SSCollectionViewItem *item in items) {
+ [_visibleItemPointers removeObject:[NSValue valueWithPointer:item]];
+ }
+}
+
+
- (CGSize)_itemSizeForSection:(NSInteger)section {
// TODO: Cache this value to elminate lots of method calls
if ([_delegate respondsToSelector:@selector(collectionView:itemSizeForSection:)] == NO) {
@@ -138,7 +181,7 @@ - (NSArray *)_itemsForRowIndexPath:(NSIndexPath *)rowIndexPath {
NSInteger startIndex = itemsPerRow * (NSInteger)rowIndexPath.row;
NSInteger endIndex = (NSInteger)fmin(totalItems, startIndex + itemsPerRow);
-
+
NSMutableArray *items = [[NSMutableArray alloc] initWithCapacity:endIndex - startIndex];
for (NSInteger i = startIndex; i < endIndex; i++) {
@@ -152,34 +195,35 @@ - (NSArray *)_itemsForRowIndexPath:(NSIndexPath *)rowIndexPath {
}
item.tag = i;
+ item.collectionView = self;
[items addObject:item];
+ [_visibleItemPointers addObject:[NSValue valueWithPointer:item]];
}
return [items autorelease];
}
-- (NSIndexPath *)_rowIndexPathForItemIndexPath:(NSIndexPath *)itemIndexPath {
- // TODO: Implement
- return nil;
+#pragma mark Getters
+
+- (UIScrollView *)scrollView {
+ return _tableView;
}
-- (NSIndexPath *)_deepRowIndexPathForItemIndexPath:(NSIndexPath *)itemIndexPath {
- // TODO: Implement
- return nil;
+- (UIView *)backgroundView {
+ return _tableView.backgroundView;
}
-#pragma mark Getters
+#pragma mark Setters
-- (UIScrollView *)scrollView {
- return _tableView;
+- (void)setBackgroundColor:(UIColor *)color {
+ [super setBackgroundColor:color];
+ _tableView.backgroundColor = color;
}
-#pragma mark Setters
-
- (void)setDataSource:(id<SSCollectionViewDataSource>)dataSource {
_dataSource = dataSource;
@@ -198,61 +242,8 @@ - (void)setDelegate:(id<SSCollectionViewDelegate>)delegate {
}
-- (void)setFrame:(CGRect)rect {
- [super setFrame:rect];
-
- [UIView beginAnimations:@"SSCollectionViewAnimationUpdateLayout" context:self];
- [self setNeedsLayout];
- [UIView commitAnimations];
-}
-
-
- (void)setBackgroundView:(UIView *)background {
- [_backgroundView removeFromSuperview];
- [_backgroundView release];
-
- _backgroundView = [background retain];
- _backgroundView.tag = -1;
- _backgroundView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
- [self insertSubview:_backgroundView atIndex:0];
-
- [self setNeedsLayout];
-}
-
-
-- (void)setBackgroundHeaderView:(UIView *)backgroundHeader {
- [_backgroundHeaderView removeFromSuperview];
- [_backgroundHeaderView release];
-
- _backgroundHeaderView = [backgroundHeader retain];
- _backgroundHeaderView.tag = -2;
- _backgroundHeaderView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
-
- if (_backgroundView) {
- [self insertSubview:_backgroundHeaderView aboveSubview:_backgroundView];
- } else {
- [self insertSubview:_backgroundHeaderView atIndex:0];
- }
-
- [self setNeedsLayout];
-}
-
-
-- (void)setBackgroundFooterView:(UIView *)backgroundFooter {
- [_backgroundFooterView removeFromSuperview];
- [_backgroundFooterView release];
-
- _backgroundFooterView = [backgroundFooter retain];
- _backgroundFooterView.tag = -3;
- _backgroundFooterView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
-
- if (_backgroundView) {
- [self insertSubview:_backgroundFooterView aboveSubview:_backgroundView];
- } else {
- [self insertSubview:_backgroundFooterView atIndex:0];
- }
-
- [self setNeedsLayout];
+ _tableView.backgroundView = background;
}
@@ -282,16 +273,18 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N
SSCollectionViewTableViewCell *cell = (SSCollectionViewTableViewCell *)[_tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (!cell) {
- cell = [[SSCollectionViewTableViewCell alloc] initWithReuseIdentifier:cellIdentifier];
+ cell = [[[SSCollectionViewTableViewCell alloc] initWithReuseIdentifier:cellIdentifier] autorelease];
}
// TODO: Cache
CGSize itemSize = [self _itemSizeForSection:indexPath.section];
CGFloat itemsPerRow = floorf(self.frame.size.width / (itemSize.width + _minimumColumnSpacing));
+ CGFloat itemSpacing = roundf((self.frame.size.width - (itemSize.width * itemsPerRow)) / itemsPerRow);
cell.itemSize = itemSize;
- cell.itemSpacing = roundf((self.frame.size.width - (itemSize.width * itemsPerRow)) / itemsPerRow);
+ cell.itemSpacing = itemSpacing;
cell.items = [self _itemsForRowIndexPath:indexPath];
+ cell.collectionView = nil;
return cell;
}
@@ -14,6 +14,7 @@ typedef enum {
} SSCollectionViewItemStyle;
@class SSLabel;
+@class SSCollectionView;
/**
@brief View for display in a collection view.
@@ -31,6 +32,8 @@ typedef enum {
BOOL _selected;
BOOL _highlighted;
+
+ SSCollectionView *_collectionView;
}
/**
Oops, something went wrong.

0 comments on commit a12ab59

Please sign in to comment.