diff --git a/StreamView/EKStreamView.h b/StreamView/EKStreamView.h index 389d7ca..7724b82 100644 --- a/StreamView/EKStreamView.h +++ b/StreamView/EKStreamView.h @@ -40,6 +40,11 @@ @optional +- (UIView *)headerForStreamView:(EKStreamView *)streamView; +- (UIView *)footerForStreamView:(EKStreamView *)streamView; + +@optional + @end @@ -54,11 +59,11 @@ NSMutableArray *cellHeightsByIndex, // 1d *cellHeightsByColumn, // 2d - *heightsForColumns, // 1d *rectsForCells; // 2d EKWaterfallCellInfo NSMutableDictionary *cellCache; // reuseIdentifier => NSMutableArray NSSet *visibleCellInfo; + UIView *headerView, *footerView; } @property (nonatomic, assign) id delegate; diff --git a/StreamView/EKStreamView.m b/StreamView/EKStreamView.m index 1ac6aaf..d7652fc 100644 --- a/StreamView/EKStreamView.m +++ b/StreamView/EKStreamView.m @@ -84,10 +84,12 @@ - (void)dealloc [[super delegate] release]; [cellHeightsByIndex release]; [cellHeightsByColumn release]; - [heightsForColumns release]; [rectsForCells release]; [visibleCellInfo release]; [cellCache release]; + + [headerView release]; + [footerView release]; [super dealloc]; } @@ -95,10 +97,27 @@ - (void)reloadData { [cellHeightsByIndex removeAllObjects]; [cellHeightsByColumn removeAllObjects]; - [heightsForColumns removeAllObjects]; [rectsForCells removeAllObjects]; [cellCache removeAllObjects]; + if ([delegate respondsToSelector:@selector(headerForStreamView:)]) { + headerView = [[delegate headerForStreamView:self] retain]; + CGRect f = headerView.frame; + f.origin = CGPointZero; + headerView.frame = f; + + [self addSubview:headerView]; + } else { + headerView = nil; + } + + if ([delegate respondsToSelector:@selector(footerForStreamView:)]) { + footerView = [[delegate footerForStreamView:self] retain]; + [self addSubview:footerView]; + } else { + footerView = nil; + } + // calculate height for all cells NSInteger numberOfColumns = [delegate numberOfColumnsInStreamView:self]; if (numberOfColumns < 1) @@ -113,11 +132,12 @@ - (void)reloadData CGFloat columnWidth = self.frame.size.width / numberOfColumns; + CGFloat cellHeight = headerView ? headerView.frame.size.height : 0.0f; for (int i = 0; i < numberOfColumns; i++) { [cellHeightsByColumn addObject:[NSMutableArray arrayWithCapacity:20]]; [rectsForCells addObject:[NSMutableArray arrayWithCapacity:20]]; - [heightsForColumns addObject:[NSNumber numberWithFloat:0.0f]]; cellX[i] = (i == 0 ? 0.0f : cellX[i - 1] + columnWidth); + columnHeights[i] = cellHeight; } for (int i = 0; i < numberOfCells; i++) { @@ -159,11 +179,16 @@ - (void)reloadData maxHeight = columnHeights[i]; } + if (footerView) { + CGRect f = footerView.frame; + f.origin = CGPointMake(0.0f, maxHeight); + footerView.frame = f; + + maxHeight += footerView.frame.size.height; + } + self.contentSize = CGSizeMake(0.0f, maxHeight); - for (int i = 0; i < numberOfColumns; i++) { - [heightsForColumns addObject:[NSNumber numberWithFloat:columnHeights[i]]]; - } free(columnHeights); free(cellX); @@ -226,7 +251,6 @@ - (void)setup cellHeightsByIndex = [[NSMutableArray alloc] initWithCapacity:30]; cellHeightsByColumn = [[NSMutableArray alloc] initWithCapacity:5]; - heightsForColumns = [[NSMutableArray alloc] initWithCapacity:5]; rectsForCells = [[NSMutableArray alloc] initWithCapacity:5]; cellCache = [[NSMutableDictionary alloc] initWithCapacity:5]; } diff --git a/StreamView/EKViewController.m b/StreamView/EKViewController.m index d3da141..d875fbf 100644 --- a/StreamView/EKViewController.m +++ b/StreamView/EKViewController.m @@ -95,4 +95,20 @@ - (CGFloat)streamView:(EKStreamView *)streamView heightForCellAtIndex:(NSInteger return [[randomHeights objectAtIndex:index] floatValue]; } +- (UIView *)headerForStreamView:(EKStreamView *)streamView +{ + MyCell *header = [[[MyCell alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 60)] autorelease]; + header.label.text = @"This is the header"; + + return header; +} + +- (UIView *)footerForStreamView:(EKStreamView *)streamView +{ + MyCell *footer = [[[MyCell alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 60)] autorelease]; + footer.label.text = @"This is the footer"; + + return footer; +} + @end