Skip to content

Commit

Permalink
Remove one delegate method. Add dequeueReusableCellWithIdentifier met…
Browse files Browse the repository at this point in the history
…hod. Now it works like UITableView. We can have different types of cells now.
  • Loading branch information
Xenofex committed Jan 17, 2012
1 parent abb8871 commit 61314bc
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 158 deletions.
16 changes: 11 additions & 5 deletions StreamView/EKStreamView.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@

#import <UIKit/UIKit.h>

@protocol EKResusableCell <NSObject>

@property (nonatomic, retain) NSString *reuseIdentifier;

@end



@interface EKStreamViewCellInfo : NSObject
Expand All @@ -16,7 +22,7 @@
@property (nonatomic, assign) NSUInteger index;

// You SHOULD ONLY access this property when this object is in visibleCellInfo!
@property (nonatomic, assign) UIView *cell;
@property (nonatomic, assign) UIView<EKResusableCell> *cell;

@end

Expand All @@ -29,9 +35,8 @@

- (NSInteger)numberOfCellsInStreamView:(EKStreamView *)streamView;
- (NSInteger)numberOfColumnsInStreamView:(EKStreamView *)streamView;
- (UIView *)cellForStreamView:(EKStreamView *)streamView;
- (UIView<EKResusableCell> *)cellForStreamView:(EKStreamView *)streamView atIndex:(NSInteger)index;
- (CGFloat)streamView:(EKStreamView *)streamView heightForCellAtIndex:(NSInteger)index;
- (void)streamView:(EKStreamView *)streamView setContentForCell:(UIView *)cell atIndex:(NSInteger)index;

@optional

Expand All @@ -50,14 +55,15 @@
*cellHeightsByIndex, // 1d
*cellHeightsByColumn, // 2d
*heightsForColumns, // 1d
*rectsForCells, // 2d EKWaterfallCellInfo
*cellPool; // 1d UIView
*rectsForCells; // 2d EKWaterfallCellInfo

NSMutableDictionary *cellCache; // reuseIdentifier => NSMutableArray
NSSet *visibleCellInfo;
}

@property (nonatomic, assign) id<EKStreamViewDelegate> delegate;

- (id<EKResusableCell>)dequeueReusableCellWithIdentifier:(NSString *)identifier;
- (void)reloadData;

@end
59 changes: 29 additions & 30 deletions StreamView/EKStreamView.m
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,10 @@ @interface EKStreamView()

- (void)setup;
- (NSSet *)getVisibleCellInfo;
- (UIView *)getCell;
- (void)layoutCellWithCellInfo:(EKStreamViewCellInfo *)info;

@property (nonatomic, retain) NSSet *visibleCellInfo;
@property (nonatomic, retain) NSMutableArray *cellPool;
@property (nonatomic, retain) NSMutableDictionary *cellCache;

@end

Expand All @@ -60,7 +59,7 @@ - (void)layoutCellWithCellInfo:(EKStreamViewCellInfo *)info;

@implementation EKStreamView

@synthesize delegate, visibleCellInfo, cellPool;
@synthesize delegate, visibleCellInfo, cellCache;

- (id)initWithFrame:(CGRect)frame
{
Expand Down Expand Up @@ -88,7 +87,7 @@ - (void)dealloc
[heightsForColumns release];
[rectsForCells release];
[visibleCellInfo release];
[cellPool release];
[cellCache release];
[super dealloc];
}

Expand All @@ -98,7 +97,7 @@ - (void)reloadData
[cellHeightsByColumn removeAllObjects];
[heightsForColumns removeAllObjects];
[rectsForCells removeAllObjects];
[cellPool removeAllObjects];
[cellCache removeAllObjects];

// calculate height for all cells
NSInteger numberOfColumns = [delegate numberOfColumnsInStreamView:self];
Expand Down Expand Up @@ -170,6 +169,18 @@ - (void)reloadData
free(cellX);
}

- (id<EKResusableCell>)dequeueReusableCellWithIdentifier:(NSString *)identifier
{
NSMutableArray *cellArray = [cellCache objectForKey:identifier];
id<EKResusableCell> cell = nil;
if ([cellArray count] > 0) {
cell = [[[cellArray lastObject] retain] autorelease];
[cellArray removeLastObject];
}

return cell;
}

#pragma mark - Private Methods

- (NSSet *)getVisibleCellInfo
Expand Down Expand Up @@ -199,24 +210,10 @@ - (NSSet *)getVisibleCellInfo
return ret;
}

- (UIView *)getCell
{
UIView *cell;
if ([cellPool count] > 0) {
cell = [[[cellPool lastObject] retain] autorelease];
[cellPool removeLastObject];
} else {
cell = [delegate cellForStreamView:self];
}

return cell;
}

- (void)layoutCellWithCellInfo:(EKStreamViewCellInfo *)info
{
UIView *cell = [self getCell];
UIView<EKResusableCell> *cell = [delegate cellForStreamView:self atIndex:info.index];
cell.frame = info.frame;
[delegate streamView:self setContentForCell:cell atIndex:info.index];
info.cell = cell;
[self addSubview:cell];
}
Expand All @@ -231,7 +228,7 @@ - (void)setup
cellHeightsByColumn = [[NSMutableArray alloc] initWithCapacity:5];
heightsForColumns = [[NSMutableArray alloc] initWithCapacity:5];
rectsForCells = [[NSMutableArray alloc] initWithCapacity:5];
cellPool = [[NSMutableArray alloc] initWithCapacity:20];
cellCache = [[NSMutableDictionary alloc] initWithCapacity:5];
}

@end
Expand All @@ -240,13 +237,6 @@ - (void)setup



// TODO: in scrollView did scroll to position delegate method,
// 1. determine which cells should be visible
// 2. compare should-be-visible list to the current visibleCells list
// For any missing cells, deque and setup it to the position;
// for any cells that is there but not in should-be-visible list, remove it and put it into the queue.


@implementation EKStreamViewUIScrollViewDelegate

@synthesize streamView;
Expand All @@ -255,11 +245,20 @@ - (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
NSSet *newVisibleCellInfo = [streamView getVisibleCellInfo];
NSSet *visibleCellInfo = streamView.visibleCellInfo;
NSMutableArray *cellPool = streamView.cellPool;
NSMutableDictionary *cellCache = streamView.cellCache;


for (EKStreamViewCellInfo *info in visibleCellInfo) {
if (![newVisibleCellInfo containsObject:info]) {
// info.cell.retainCount: 1
[cellPool addObject:info.cell];
NSString *cellID = info.cell.reuseIdentifier;
NSMutableArray *cellArray = [cellCache objectForKey:cellID];
if (cellArray == nil) {
cellArray = [NSMutableArray arrayWithCapacity:10];
[cellCache setObject:cellArray forKey:cellID];
}

[cellArray addObject:info.cell];
// info.cell.retainCount: 2
[info.cell removeFromSuperview];
// info.cell.retainCount: 1
Expand Down
22 changes: 20 additions & 2 deletions StreamView/EKViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,27 @@ - (NSInteger)numberOfColumnsInStreamView:(EKStreamView *)streamView
return 3;
}

- (UIView *)cellForStreamView:(EKStreamView *)streamView
- (UIView *)cellForStreamView:(EKStreamView *)streamView atIndex:(NSInteger)index
{
return [[[MyCell alloc] initWithFrame:CGRectMake(0, 0, 100, 100)] autorelease];
static NSString *CellID1 = @"MyCell1";
static NSString *CellID2 = @"MyCell2";

BOOL redCell = index % 3 == 0;
NSString *CellID = CellID1;

MyCell *cell;

cell = (MyCell *)[streamView dequeueReusableCellWithIdentifier:CellID];

if (cell == nil) {
cell = [[[MyCell alloc] initWithFrame:CGRectMake(0, 0, 100, 100)] autorelease];
cell.reuseIdentifier = CellID;
// if (redCell) cell.label.textColor = [UIColor redColor];
}

cell.label.text = [NSString stringWithFormat:@"%d",index];

return cell;
}

- (CGFloat)streamView:(EKStreamView *)streamView heightForCellAtIndex:(NSInteger)index
Expand Down
6 changes: 5 additions & 1 deletion StreamView/MyCell.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,12 @@
//

#import <UIKit/UIKit.h>
#import "EKStreamView.h"

@interface MyCell : UIView
@interface MyCell : UIView<EKResusableCell>
{
NSString *reuseIdentifier;
}

@property (nonatomic, readonly) UILabel *label;

Expand Down
3 changes: 2 additions & 1 deletion StreamView/MyCell.m
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,13 @@

@implementation MyCell

@synthesize label;
@synthesize label, reuseIdentifier;


- (void)dealloc
{
[label release];
[reuseIdentifier release];
[super dealloc];
}

Expand Down
119 changes: 0 additions & 119 deletions StreamView/en.lproj/EKViewController.xib

This file was deleted.

0 comments on commit 61314bc

Please sign in to comment.