diff --git a/GMGridView/GMGridView.h b/GMGridView/GMGridView.h index 7282e1d..a60653b 100644 --- a/GMGridView/GMGridView.h +++ b/GMGridView/GMGridView.h @@ -88,6 +88,7 @@ typedef enum @property (nonatomic) BOOL disableEditOnEmptySpaceTap; // Default is NO @property (nonatomic, readonly) UIScrollView *scrollView __attribute__((deprecated)); // The grid now inherits directly from UIScrollView +@property (nonatomic, strong) UIView *gridHeaderView; // Default is nil // Reusable cells - (GMGridViewCell *)dequeueReusableCell; // Should be called in GMGridView:cellForItemAtIndex: to reuse a cell diff --git a/GMGridView/GMGridView.m b/GMGridView/GMGridView.m index c362c29..e6ea90f 100644 --- a/GMGridView/GMGridView.m +++ b/GMGridView/GMGridView.m @@ -106,6 +106,7 @@ - (BOOL)isInTransformingState; // Helpers & more - (void)recomputeSizeAnimated:(BOOL)animated; - (void)relayoutItemsAnimated:(BOOL)animated; +- (void)relayoutGridHeaderView:(BOOL)animated; - (NSArray *)itemSubviews; - (GMGridViewCell *)cellForItemAtIndex:(NSInteger)position; - (GMGridViewCell *)newItemSubViewForPosition:(NSInteger)position; @@ -147,6 +148,8 @@ @implementation GMGridView @synthesize enableEditOnLongPress; @synthesize disableEditOnEmptySpaceTap; +@synthesize gridHeaderView = _gridHeaderView; + @synthesize itemsSubviewsCacheIsValid = _itemsSubviewsCacheIsValid; @synthesize itemSubviewsCache; @@ -249,6 +252,7 @@ - (void)commonInit self.showFullSizeViewWithAlphaWhenTransforming = YES; self.minEdgeInsets = UIEdgeInsetsMake(5, 5, 5, 5); self.clipsToBounds = NO; + self.gridHeaderView = nil; _sortFuturePosition = GMGV_INVALID_POSITION; _itemSize = CGSizeZero; @@ -291,6 +295,7 @@ - (void)layoutSubviewsWithAnimation:(GMGridViewItemAnimation)animation { [self recomputeSizeAnimated:!(animation & GMGridViewItemAnimationNone)]; [self relayoutItemsAnimated:animation & GMGridViewItemAnimationFade]; // only supported animation for now + [self relayoutGridHeaderView:!(animation & GMGridViewItemAnimationNone)]; [self loadRequiredItems]; } @@ -456,6 +461,17 @@ - (void)setEditing:(BOOL)editing animated:(BOOL)animated } } +- (void)setGridHeaderView:(UIView *)gridHeaderView +{ + if (_gridHeaderView == gridHeaderView) return; + + if (_gridHeaderView) [_gridHeaderView removeFromSuperview]; + _gridHeaderView = gridHeaderView; + if (_gridHeaderView) [self.scrollView addSubview:_gridHeaderView]; + + [self setNeedsLayout]; +} + ////////////////////////////////////////////////////////////// #pragma mark UIScrollView delegate replacement ////////////////////////////////////////////////////////////// @@ -1265,7 +1281,12 @@ - (NSInteger)positionForItemSubview:(GMGridViewCell *)view - (void)recomputeSizeAnimated:(BOOL)animated { - [self.layoutStrategy setupItemSize:_itemSize andItemSpacing:self.itemSpacing withMinEdgeInsets:self.minEdgeInsets andCenteredGrid:self.centerGrid]; + UIEdgeInsets minEdgeInsets = self.minEdgeInsets; + if (self.gridHeaderView) { + minEdgeInsets.top += self.gridHeaderView.bounds.size.height; + } + + [self.layoutStrategy setupItemSize:_itemSize andItemSpacing:self.itemSpacing withMinEdgeInsets:minEdgeInsets andCenteredGrid:self.centerGrid]; [self.layoutStrategy rebaseWithItemCount:_numberTotalItems insideOfBounds:self.bounds]; CGSize contentSize = [self.layoutStrategy contentSize]; @@ -1766,6 +1787,25 @@ - (void)swapObjectAtIndex:(NSInteger)index1 withObjectAtIndex:(NSInteger)index2 }]; } +- (void)relayoutGridHeaderView:(BOOL)animated; +{ + CGRect frame = CGRectMake(0, 0, self.bounds.size.width, self.gridHeaderView.bounds.size.height); + if (animated) + { + [UIView animateWithDuration:kDefaultAnimationDuration + delay:0 + options:kDefaultAnimationOptions + animations:^{ + self.gridHeaderView.frame = frame; + } + completion:nil + ]; + } + else + { + self.gridHeaderView.frame = frame; + } +} ////////////////////////////////////////////////////////////// #pragma mark depracated public methods diff --git a/GMGridView/GMGridView.xcodeproj/project.pbxproj b/GMGridView/GMGridView.xcodeproj/project.pbxproj index d2fb491..ee8a4fb 100644 --- a/GMGridView/GMGridView.xcodeproj/project.pbxproj +++ b/GMGridView/GMGridView.xcodeproj/project.pbxproj @@ -12,13 +12,13 @@ 16A0361514A012EF0062437D /* UIView+GMGridViewAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 16A0361314A012EF0062437D /* UIView+GMGridViewAdditions.h */; }; 16A0361614A012EF0062437D /* UIView+GMGridViewAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 16A0361414A012EF0062437D /* UIView+GMGridViewAdditions.m */; }; 78509316149FAC2E000787E4 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 78509315149FAC2E000787E4 /* Foundation.framework */; }; - 78509341149FAC61000787E4 /* GMGridView-Constants.h in Headers */ = {isa = PBXBuildFile; fileRef = 78509335149FAC61000787E4 /* GMGridView-Constants.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 78509342149FAC61000787E4 /* GMGridView.h in Headers */ = {isa = PBXBuildFile; fileRef = 78509336149FAC61000787E4 /* GMGridView.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 78509341149FAC61000787E4 /* GMGridView-Constants.h in Headers */ = {isa = PBXBuildFile; fileRef = 78509335149FAC61000787E4 /* GMGridView-Constants.h */; settings = {ATTRIBUTES = (); }; }; + 78509342149FAC61000787E4 /* GMGridView.h in Headers */ = {isa = PBXBuildFile; fileRef = 78509336149FAC61000787E4 /* GMGridView.h */; settings = {ATTRIBUTES = (); }; }; 78509343149FAC61000787E4 /* GMGridView.m in Sources */ = {isa = PBXBuildFile; fileRef = 78509337149FAC61000787E4 /* GMGridView.m */; }; - 78509344149FAC61000787E4 /* GMGridViewCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 78509338149FAC61000787E4 /* GMGridViewCell.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 78509344149FAC61000787E4 /* GMGridViewCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 78509338149FAC61000787E4 /* GMGridViewCell.h */; settings = {ATTRIBUTES = (); }; }; 78509345149FAC61000787E4 /* GMGridViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 78509339149FAC61000787E4 /* GMGridViewCell.m */; }; - 78509346149FAC61000787E4 /* GMGridViewCell+Extended.h in Headers */ = {isa = PBXBuildFile; fileRef = 7850933A149FAC61000787E4 /* GMGridViewCell+Extended.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 78509347149FAC61000787E4 /* GMGridViewLayoutStrategies.h in Headers */ = {isa = PBXBuildFile; fileRef = 7850933B149FAC61000787E4 /* GMGridViewLayoutStrategies.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 78509346149FAC61000787E4 /* GMGridViewCell+Extended.h in Headers */ = {isa = PBXBuildFile; fileRef = 7850933A149FAC61000787E4 /* GMGridViewCell+Extended.h */; settings = {ATTRIBUTES = (); }; }; + 78509347149FAC61000787E4 /* GMGridViewLayoutStrategies.h in Headers */ = {isa = PBXBuildFile; fileRef = 7850933B149FAC61000787E4 /* GMGridViewLayoutStrategies.h */; settings = {ATTRIBUTES = (); }; }; 78509348149FAC61000787E4 /* GMGridViewLayoutStrategies.m in Sources */ = {isa = PBXBuildFile; fileRef = 7850933C149FAC61000787E4 /* GMGridViewLayoutStrategies.m */; }; 78509350149FAC71000787E4 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7850934D149FAC71000787E4 /* QuartzCore.framework */; }; 78509351149FAC71000787E4 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7850934E149FAC71000787E4 /* UIKit.framework */; }; diff --git a/GMGridView/GMGridViewLayoutStrategies.m b/GMGridView/GMGridViewLayoutStrategies.m index 71919ad..114dbf2 100644 --- a/GMGridView/GMGridViewLayoutStrategies.m +++ b/GMGridView/GMGridViewLayoutStrategies.m @@ -222,7 +222,7 @@ - (NSRange)rangeOfPositionsInBoundsFromOffset:(CGPoint)offset CGFloat itemHeight = self.itemSize.height + self.itemSpacing; - CGFloat firstRow = MAX(0, (int)(contentOffset.y / itemHeight) - 1); + CGFloat firstRow = MAX(0, (int)((contentOffset.y-self.edgeInsets.top) / itemHeight) - 1); CGFloat lastRow = ceil((contentOffset.y + self.gridBounds.size.height) / itemHeight);