From b128ad4eb058764cb1308594ab2b21bff019f290 Mon Sep 17 00:00:00 2001 From: Ran Tavory Date: Wed, 16 Nov 2011 08:48:23 +0200 Subject: [PATCH 01/13] Add pagingEnabled to the grid. It simply delegates the property back to the undelying scrollView --- GMGridView/API/GMGridView.h | 1 + GMGridView/API/GMGridView.m | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/GMGridView/API/GMGridView.h b/GMGridView/API/GMGridView.h index 3761e3f..2c74ab0 100644 --- a/GMGridView/API/GMGridView.h +++ b/GMGridView/API/GMGridView.h @@ -71,6 +71,7 @@ typedef enum @property (nonatomic) UIEdgeInsets minEdgeInsets; // Default is (5, 5, 5, 5) @property (nonatomic) CFTimeInterval minimumPressDuration; // Default is 0.2; if set to 0, the scrollView will not be scrollable @property (nonatomic) BOOL showFullSizeViewWithAlphaWhenTransforming; // Default is YES - not working right now +@property (nonatomic) BOOL pagingEnabled; // Default is NO // Reusable cells diff --git a/GMGridView/API/GMGridView.m b/GMGridView/API/GMGridView.m index ce0a07e..34f8eb6 100644 --- a/GMGridView/API/GMGridView.m +++ b/GMGridView/API/GMGridView.m @@ -318,6 +318,16 @@ - (void)setEditing:(BOOL)editing } } +- (void)setPagingEnabled:(BOOL)pagingEnabled +{ + _scrollView.pagingEnabled = pagingEnabled; +} + +- (BOOL)isPagingEnabled +{ + return _scrollView.pagingEnabled; +} + ////////////////////////////////////////////////////////////// #pragma mark UIScrollView delegate ////////////////////////////////////////////////////////////// From d58ccf1da4f83e00f8dc8d420dc9945cbddb767e Mon Sep 17 00:00:00 2001 From: Ran Tavory Date: Wed, 16 Nov 2011 09:47:11 +0200 Subject: [PATCH 02/13] Fix name of isPagingEnabled to pagingEnabled. Old java habits... --- GMGridView/API/GMGridView.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GMGridView/API/GMGridView.m b/GMGridView/API/GMGridView.m index 34f8eb6..07ab8ad 100644 --- a/GMGridView/API/GMGridView.m +++ b/GMGridView/API/GMGridView.m @@ -323,7 +323,7 @@ - (void)setPagingEnabled:(BOOL)pagingEnabled _scrollView.pagingEnabled = pagingEnabled; } -- (BOOL)isPagingEnabled +- (BOOL)pagingEnabled { return _scrollView.pagingEnabled; } From abf5a73a4b7b6d9ca269ec7b53df258be7f2d52e Mon Sep 17 00:00:00 2001 From: Ran Tavory Date: Wed, 16 Nov 2011 12:23:28 +0200 Subject: [PATCH 03/13] Implement GMGridViewLayoutHorizontalPagedLtr. a layout for paged horizontal scroll where items in each page flow from top-left to bottom-right --- GMGridView/API/GMGridViewLayoutStrategies.h | 30 ++++++- GMGridView/API/GMGridViewLayoutStrategies.m | 94 +++++++++++++++++++++ 2 files changed, 123 insertions(+), 1 deletion(-) diff --git a/GMGridView/API/GMGridViewLayoutStrategies.h b/GMGridView/API/GMGridViewLayoutStrategies.h index 13a6f49..23fc3ed 100644 --- a/GMGridView/API/GMGridViewLayoutStrategies.h +++ b/GMGridView/API/GMGridViewLayoutStrategies.h @@ -35,7 +35,20 @@ typedef enum { GMGridViewLayoutVertical = 0, - GMGridViewLayoutHorizontal + GMGridViewLayoutHorizontal, + // A paged horizontal strategy in which in each page the items flow from top left to bottom right + // Example: + // ______________________ + // | 1 2 3 | 10 11 12 | + // | 4 5 6 | 13 14 | + // | 7 8 9 | | + // ---------------------- + // NOTE: For this strategy to work properly and center the elements in each page, make sure that + // the grid's left inset is zero. For example: + // gmGridView.minEdgeInsets = UIEdgeInsetsMake(6, 0, 0, 0); + // as well as that paging is enabled for this grid: + // gmGridView.pagingEnabled = YES; + GMGridViewLayoutHorizontalPagedLtr } GMGridViewLayoutStrategyType; @@ -127,5 +140,20 @@ typedef enum { @end +////////////////////////////////////////////////////////////// +#pragma mark - Horizontal Paged LTR strategy +////////////////////////////////////////////////////////////// + +@interface GMGridViewLayoutHorizontalPagedLtrStrategy : GMGridViewLayoutHorizontalStrategy +{ +@protected + NSUInteger _numberOfPages; + NSUInteger _numberOfColumnsPerPage; + // left padding on each page. So that the content can be centered in the page + CGFloat _pagePaddingLeft; +} +@property (nonatomic, readonly) NSUInteger numberOfPages; +@property (nonatomic, readonly) NSUInteger numberOfColumnsPerPage; +@end diff --git a/GMGridView/API/GMGridViewLayoutStrategies.m b/GMGridView/API/GMGridViewLayoutStrategies.m index 32953dc..9a9523f 100644 --- a/GMGridView/API/GMGridViewLayoutStrategies.m +++ b/GMGridView/API/GMGridViewLayoutStrategies.m @@ -43,6 +43,9 @@ @implementation GMGridViewLayoutStrategyFactory case GMGridViewLayoutVertical: strategy = [[GMGridViewLayoutVerticalStrategy alloc] init]; break; + case GMGridViewLayoutHorizontalPagedLtr: + strategy = [[GMGridViewLayoutHorizontalPagedLtrStrategy alloc] init]; + break; case GMGridViewLayoutHorizontal: default: strategy = [[GMGridViewLayoutHorizontalStrategy alloc] init]; @@ -280,11 +283,102 @@ - (NSRange)rangeOfPositionsInBoundsFromOffset:(CGPoint)offset @end +////////////////////////////////////////////////////////////// +#pragma mark - +#pragma mark - Horizontal Paged LTR strategy implementation +////////////////////////////////////////////////////////////// +@implementation GMGridViewLayoutHorizontalPagedLtrStrategy +@synthesize numberOfPages = _numberOfPages; +@synthesize numberOfColumnsPerPage = _numberOfColumnsPerPage; +- (id)init +{ + if ((self = [super init])) + { + _type = GMGridViewLayoutHorizontalPagedLtr; + } + return self; +} +- (void)rebaseWithItemCount:(NSInteger)count havingSize:(CGSize)itemSize andSpacing:(NSInteger)spacing insideOfBounds:(CGRect)bounds +{ + [super rebaseWithItemCount:count havingSize:itemSize andSpacing:spacing insideOfBounds:bounds]; + _numberOfPages = ceil(self.contentSize.width / bounds.size.width); + _contentSize.width = _numberOfPages * bounds.size.width; + _numberOfColumnsPerPage = floor(bounds.size.width / (itemSize.width + spacing)); + + // The total size of each page's 'content' area from which the left padding will be calculated so that the content can be centered in the page + NSUInteger pageContentwidth = _numberOfColumnsPerPage * (itemSize.width + spacing) - spacing; + _pagePaddingLeft = (bounds.size.width - pageContentwidth) / 2; +} +- (CGPoint)originForItemAtColumn:(NSInteger)column row:(NSInteger)row page:(NSInteger)page +{ + CGFloat x = page * self.contentBounds.size.width + _pagePaddingLeft + column * (self.itemSize.width + self.itemSpacing); + CGFloat y = row * (self.itemSize.height + self.itemSpacing); + return CGPointMake(x, y); +} +- (CGPoint)originForItemAtPosition:(NSInteger)position +{ + // page, column and row are zero based + NSUInteger page = floor(position / (self.numberOfColumnsPerPage * self.numberOfItemsPerColumn)); + NSUInteger column = position % self.numberOfColumnsPerPage; // The columns is a column within the page + NSUInteger row = (NSUInteger) floor(position / self.numberOfColumnsPerPage) % self.numberOfItemsPerColumn; + return [self originForItemAtColumn:column row:row page:page]; +} +- (NSInteger)itemPositionFromLocation:(CGPoint)location +{ + NSUInteger page = floor(location.x / self.contentBounds.size.width); + NSUInteger column = (location.x - page * self.contentBounds.size.width - _pagePaddingLeft) / (self.itemSize.width + self.itemSpacing); + NSUInteger row = (int) (location.y / (self.itemSize.height + self.itemSpacing)); + + NSInteger position = page * self.numberOfItemsPerColumn * self.numberOfColumnsPerPage + row * self.numberOfColumnsPerPage + column; + + if (position >= [self itemCount] || position < 0) + { + position = GMGV_INVALID_POSITION; + } + else + { + CGPoint itemOrigin = [self originForItemAtPosition:position]; + CGRect itemFrame = CGRectMake(itemOrigin.x, + itemOrigin.y, + self.itemSize.width, + self.itemSize.height); + + if (!CGRectContainsPoint(itemFrame, location)) + { + position = GMGV_INVALID_POSITION; + } + } + + return position; +} + +- (NSRange) rangeOfPositionsFromPage:(NSUInteger)page +{ + NSUInteger itemsPerPage = self.numberOfItemsPerColumn * self.numberOfColumnsPerPage; + // in theory it's correct to return the following: + //return NSMakeRange(page * itemsPerPage, itemsPerPage); + // however, if we do that, scrolling would not work smmothly and users would notice the cells being loaded + // with each page transition. + // Therefore instead, we return a larger range which includes two more pages, one to the left of this page and another to the right + // It comes on the expense of memory, but provides smoother experience + NSUInteger pageToTheLeft = page == 0 ? 0 : page - 1; + NSUInteger pageToTheRight = page == self.numberOfPages ? page : page + 1; + return NSMakeRange(pageToTheLeft * itemsPerPage, (pageToTheRight - pageToTheLeft + 1) * itemsPerPage); +} +- (NSRange)rangeOfPositionsInBoundsFromOffset:(CGPoint)offset +{ + CGPoint contentOffset = CGPointMake(MAX(0, offset.x), + MAX(0, offset.y)); + NSUInteger page = floor(contentOffset.x / _contentBounds.size.width); + return [self rangeOfPositionsFromPage:page]; +} + +@end From 35b4bdaa98c44eee2a7812994ef18d49e2c680fb Mon Sep 17 00:00:00 2001 From: Ran Tavory Date: Wed, 16 Nov 2011 15:44:16 +0200 Subject: [PATCH 04/13] Add convertScrolledPoint and convertScrolledRect so users of GMGridView are able to get the position of a scrolled element --- GMGridView/API/GMGridView.h | 6 ++++++ GMGridView/API/GMGridView.m | 12 +++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/GMGridView/API/GMGridView.h b/GMGridView/API/GMGridView.h index 2c74ab0..2596def 100644 --- a/GMGridView/API/GMGridView.h +++ b/GMGridView/API/GMGridView.h @@ -85,6 +85,12 @@ typedef enum - (void)swapObjectAtIndex:(NSInteger)index1 withObjectAtIndex:(NSInteger)index2; - (void)scrollToObjectAtIndex:(NSInteger)index; +// Geometry + +// converts a point, taking into account the internal scroll view +- (CGPoint) convertScrolledPoint:(CGPoint)point toView:(UIView*)view; +// converts a rect, taking into account the internal scroll position +- (CGRect) convertScrolledRect:(CGRect)rect toView:(UIView*)view; @end diff --git a/GMGridView/API/GMGridView.m b/GMGridView/API/GMGridView.m index 07ab8ad..ab6bdbb 100644 --- a/GMGridView/API/GMGridView.m +++ b/GMGridView/API/GMGridView.m @@ -328,6 +328,16 @@ - (BOOL)pagingEnabled return _scrollView.pagingEnabled; } +////////////////////////////////////////////////////////////// +// Geometry +////////////////////////////////////////////////////////////// +- (CGPoint) convertScrolledPoint:(CGPoint)point toView:(UIView*)view { + return [_scrollView convertPoint:point toView:view]; +} +- (CGRect) convertScrolledRect:(CGRect)rect toView:(UIView*)view { + return [_scrollView convertRect:rect toView:view]; +} + ////////////////////////////////////////////////////////////// #pragma mark UIScrollView delegate ////////////////////////////////////////////////////////////// @@ -972,7 +982,7 @@ - (void)tapGestureUpdated:(UITapGestureRecognizer *)tapGesture { CGPoint locationTouch = [_tapGesture locationInView:_scrollView]; NSInteger position = [self.layoutStrategy itemPositionFromLocation:locationTouch]; - + if (position != GMGV_INVALID_POSITION) { [self.actionDelegate GMGridView:self didTapOnItemAtIndex:position]; From 53f7a0ed4ddb01a48619c8e32333a9c2517deff7 Mon Sep 17 00:00:00 2001 From: Ran Tavory Date: Wed, 16 Nov 2011 15:54:04 +0200 Subject: [PATCH 05/13] Add 'build' to gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index b154df8..ea089fe 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ xcuserdata/ *.xcodeproj/xcuserdata/ *.xcodeproj/project.xcworkspace/xcuserdata/ *.xcuserstate +build From 92aa779b415d74ef1bb7f23819b4a665fc166652 Mon Sep 17 00:00:00 2001 From: Ran Tavory Date: Thu, 17 Nov 2011 00:23:41 +0200 Subject: [PATCH 06/13] Add support for better programatic scroll control. Expose the contentOffset Allow scrolling to a particular point (and not only to a particular item) Add more page queries to the GMGridViewLayoutHorizontalPagedLtrStrategy ... it's all part of the same scheme... --- GMGridView/API/GMGridView.h | 4 +++- GMGridView/API/GMGridView.m | 8 ++++++++ GMGridView/API/GMGridViewLayoutStrategies.h | 4 +++- GMGridView/API/GMGridViewLayoutStrategies.m | 11 ++++++++++- 4 files changed, 24 insertions(+), 3 deletions(-) diff --git a/GMGridView/API/GMGridView.h b/GMGridView/API/GMGridView.h index 2596def..d36694d 100644 --- a/GMGridView/API/GMGridView.h +++ b/GMGridView/API/GMGridView.h @@ -72,7 +72,7 @@ typedef enum @property (nonatomic) CFTimeInterval minimumPressDuration; // Default is 0.2; if set to 0, the scrollView will not be scrollable @property (nonatomic) BOOL showFullSizeViewWithAlphaWhenTransforming; // Default is YES - not working right now @property (nonatomic) BOOL pagingEnabled; // Default is NO - +@property (nonatomic, readonly) CGPoint contentOffset; // top-left offset of the visible content (within the internal scroll view) // Reusable cells - (GMGridViewCell *)dequeueReusableCell; @@ -84,6 +84,7 @@ typedef enum - (void)reloadObjectAtIndex:(NSInteger)index; - (void)swapObjectAtIndex:(NSInteger)index1 withObjectAtIndex:(NSInteger)index2; - (void)scrollToObjectAtIndex:(NSInteger)index; +- (void)setContentOffset:(CGPoint)offset animated:(BOOL)animated; // Geometry @@ -91,6 +92,7 @@ typedef enum - (CGPoint) convertScrolledPoint:(CGPoint)point toView:(UIView*)view; // converts a rect, taking into account the internal scroll position - (CGRect) convertScrolledRect:(CGRect)rect toView:(UIView*)view; + @end diff --git a/GMGridView/API/GMGridView.m b/GMGridView/API/GMGridView.m index ab6bdbb..3ed0fd5 100644 --- a/GMGridView/API/GMGridView.m +++ b/GMGridView/API/GMGridView.m @@ -146,6 +146,7 @@ @implementation GMGridView @synthesize firstPositionLoaded = _firstPositionLoaded; @synthesize lastPositionLoaded = _lastPositionLoaded; +@synthesize contentOffset; ////////////////////////////////////////////////////////////// #pragma mark Constructors and destructor @@ -328,6 +329,13 @@ - (BOOL)pagingEnabled return _scrollView.pagingEnabled; } +- (CGPoint) contentOffset { + return _scrollView.contentOffset; +} + +- (void)setContentOffset:(CGPoint)offset animated:(BOOL)animated { + [_scrollView setContentOffset:offset animated:animated]; +} ////////////////////////////////////////////////////////////// // Geometry ////////////////////////////////////////////////////////////// diff --git a/GMGridView/API/GMGridViewLayoutStrategies.h b/GMGridView/API/GMGridViewLayoutStrategies.h index 23fc3ed..b9fb421 100644 --- a/GMGridView/API/GMGridViewLayoutStrategies.h +++ b/GMGridView/API/GMGridViewLayoutStrategies.h @@ -155,5 +155,7 @@ typedef enum { @property (nonatomic, readonly) NSUInteger numberOfPages; @property (nonatomic, readonly) NSUInteger numberOfColumnsPerPage; - +- (NSUInteger) pageForContentOffset:(CGPoint)offset; +- (CGPoint)originForItemAtColumn:(NSInteger)column row:(NSInteger)row page:(NSInteger)page; +- (CGPoint)originForPage:(NSUInteger)page; @end diff --git a/GMGridView/API/GMGridViewLayoutStrategies.m b/GMGridView/API/GMGridViewLayoutStrategies.m index 9a9523f..1acc094 100644 --- a/GMGridView/API/GMGridViewLayoutStrategies.m +++ b/GMGridView/API/GMGridViewLayoutStrategies.m @@ -332,7 +332,7 @@ - (CGPoint)originForItemAtPosition:(NSInteger)position - (NSInteger)itemPositionFromLocation:(CGPoint)location { - NSUInteger page = floor(location.x / self.contentBounds.size.width); + NSUInteger page = [self pageForContentOffset:location]; NSUInteger column = (location.x - page * self.contentBounds.size.width - _pagePaddingLeft) / (self.itemSize.width + self.itemSpacing); NSUInteger row = (int) (location.y / (self.itemSize.height + self.itemSpacing)); @@ -381,4 +381,13 @@ - (NSRange)rangeOfPositionsInBoundsFromOffset:(CGPoint)offset return [self rangeOfPositionsFromPage:page]; } +- (NSUInteger) pageForContentOffset:(CGPoint)offset +{ + return floor(offset.x / self.contentBounds.size.width); +} +- (CGPoint)originForPage:(NSUInteger)page +{ + return CGPointMake(page * self.contentBounds.size.width, 0); +} + @end From a6d30571db73c621d75a8af3e7e625bde68ffcd7 Mon Sep 17 00:00:00 2001 From: Ran Tavory Date: Thu, 17 Nov 2011 01:14:46 +0200 Subject: [PATCH 07/13] Add GMGridViewDidScroll so that users know when GMScrollView is scrolling --- GMGridView/API/GMGridView.h | 4 +++- GMGridView/API/GMGridView.m | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/GMGridView/API/GMGridView.h b/GMGridView/API/GMGridView.h index d36694d..0b8deab 100644 --- a/GMGridView/API/GMGridView.h +++ b/GMGridView/API/GMGridView.h @@ -123,7 +123,9 @@ typedef enum @required - (void)GMGridView:(GMGridView *)gridView didTapOnItemAtIndex:(NSInteger)position; - +@optional +// tells the delegate that the scroll view just did scroll. similar in concept to [UIScrollView scrollViewDidScroll:] +- (void)GMGridViewDidScroll:(GMGridView*)gridView; @end diff --git a/GMGridView/API/GMGridView.m b/GMGridView/API/GMGridView.m index 3ed0fd5..635706b 100644 --- a/GMGridView/API/GMGridView.m +++ b/GMGridView/API/GMGridView.m @@ -353,6 +353,9 @@ - (CGRect) convertScrolledRect:(CGRect)rect toView:(UIView*)view { - (void)scrollViewDidScroll:(UIScrollView *)scrollView { [self loadRequiredItems]; + if ([self.actionDelegate respondsToSelector:@selector(GMGridViewDidScroll:)]) { + [self.actionDelegate GMGridViewDidScroll:self]; + } } ////////////////////////////////////////////////////////////// From bcfa3ffa2fad0fc799d47e8c3cc9e15bf0e02677 Mon Sep 17 00:00:00 2001 From: Ran Tavory Date: Wed, 7 Dec 2011 11:54:12 +0200 Subject: [PATCH 08/13] Add support for setting showsVerticalScrollIndicator and showsHorizontalScrollIndicator --- GMGridView/API/GMGridView.h | 2 ++ GMGridView/API/GMGridView.m | 14 ++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/GMGridView/API/GMGridView.h b/GMGridView/API/GMGridView.h index 0b8deab..8a37c34 100644 --- a/GMGridView/API/GMGridView.h +++ b/GMGridView/API/GMGridView.h @@ -72,6 +72,8 @@ typedef enum @property (nonatomic) CFTimeInterval minimumPressDuration; // Default is 0.2; if set to 0, the scrollView will not be scrollable @property (nonatomic) BOOL showFullSizeViewWithAlphaWhenTransforming; // Default is YES - not working right now @property (nonatomic) BOOL pagingEnabled; // Default is NO +@property (nonatomic) BOOL showsVerticalScrollIndicator; // Default is YES +@property (nonatomic) BOOL showsHorizontalScrollIndicator; // Default is YES @property (nonatomic, readonly) CGPoint contentOffset; // top-left offset of the visible content (within the internal scroll view) // Reusable cells diff --git a/GMGridView/API/GMGridView.m b/GMGridView/API/GMGridView.m index 635706b..650454a 100644 --- a/GMGridView/API/GMGridView.m +++ b/GMGridView/API/GMGridView.m @@ -336,6 +336,20 @@ - (CGPoint) contentOffset { - (void)setContentOffset:(CGPoint)offset animated:(BOOL)animated { [_scrollView setContentOffset:offset animated:animated]; } + +- (void)setShowsVerticalScrollIndicator:(BOOL)showsVerticalScroll { + _scrollView.showsVerticalScrollIndicator = showsVerticalScroll; +} +- (BOOL)showsVerticalScrollIndicator { + return _scrollView.showsVerticalScrollIndicator; +} +- (void)setShowsHorizontalScrollIndicator:(BOOL)showsHorizontalScrollIndicator { + _scrollView.showsHorizontalScrollIndicator = showsHorizontalScrollIndicator; +} +- (BOOL)showsHorizontalScrollIndicator { + return _scrollView.showsHorizontalScrollIndicator; +} + ////////////////////////////////////////////////////////////// // Geometry ////////////////////////////////////////////////////////////// From a7199ff18c4f7bf6613f261e8649390e380127d3 Mon Sep 17 00:00:00 2001 From: Ran Tavory Date: Fri, 23 Dec 2011 15:44:26 +0200 Subject: [PATCH 09/13] Add build directory to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index b154df8..6b07d24 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ xcuserdata/ *.xcodeproj/xcuserdata/ *.xcodeproj/project.xcworkspace/xcuserdata/ *.xcuserstate +build/ From 8354e20c78984d746e2c69f6d548af061c3e143f Mon Sep 17 00:00:00 2001 From: Ran Tavory Date: Sat, 24 Dec 2011 14:46:26 +0200 Subject: [PATCH 10/13] 1. Add support for optional GMGridViewActionDelegate selector GMGridViewDidScroll: 2. Add Geometry selectors convertScrolledPoint:toView: and convertScrolledRect:rect toView: --- GMGridView/API/GMGridView.h | 9 +++++++++ GMGridView/API/GMGridView.m | 14 +++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/GMGridView/API/GMGridView.h b/GMGridView/API/GMGridView.h index 5311d54..9e4d717 100644 --- a/GMGridView/API/GMGridView.h +++ b/GMGridView/API/GMGridView.h @@ -94,6 +94,12 @@ typedef enum - (void)swapObjectAtIndex:(NSInteger)index1 withObjectAtIndex:(NSInteger)index2; - (void)scrollToObjectAtIndex:(NSInteger)index animated:(BOOL)animated; +// Geometry +// converts a point, taking into account the internal scroll view +- (CGPoint) convertScrolledPoint:(CGPoint)point toView:(UIView*)view; +// converts a rect, taking into account the internal scroll position +- (CGRect) convertScrolledRect:(CGRect)rect toView:(UIView*)view; + @end @@ -125,6 +131,9 @@ typedef enum @required - (void)GMGridView:(GMGridView *)gridView didTapOnItemAtIndex:(NSInteger)position; +@optional +// tells the delegate that the scroll view just did scroll. similar in concept to [UIScrollView scrollViewDidScroll:] +- (void)GMGridViewDidScroll:(GMGridView*)gridView; @end diff --git a/GMGridView/API/GMGridView.m b/GMGridView/API/GMGridView.m index 2d4a78a..b3550d4 100644 --- a/GMGridView/API/GMGridView.m +++ b/GMGridView/API/GMGridView.m @@ -390,6 +390,9 @@ - (BOOL)showsHorizontalScrollIndicator - (void)scrollViewDidScroll:(UIScrollView *)scrollView { [self loadRequiredItems]; + if ([self.actionDelegate respondsToSelector:@selector(GMGridViewDidScroll:)]) { + [self.actionDelegate GMGridViewDidScroll:self]; + } } ////////////////////////////////////////////////////////////// @@ -1533,5 +1536,14 @@ - (void)swapObjectAtIndex:(NSInteger)index1 withObjectAtIndex:(NSInteger)index2 ]; } - +////////////////////////////////////////////////////////////// +// Geometry +////////////////////////////////////////////////////////////// +- (CGPoint) convertScrolledPoint:(CGPoint)point toView:(UIView*)view +{ + return [_scrollView convertPoint:point toView:view]; +} +- (CGRect) convertScrolledRect:(CGRect)rect toView:(UIView*)view +{ + return [_scrollView convertRect:rect toView:view];} @end From 664af222282677ace02e1d2e6298ca54b27afb60 Mon Sep 17 00:00:00 2001 From: Ran Tavory Date: Sat, 24 Dec 2011 14:47:43 +0200 Subject: [PATCH 11/13] Add to GMGridViewLayoutHorizontalPagedStrategy the selector pageForContentOffset: --- GMGridView/API/GMGridViewLayoutStrategies.h | 2 +- GMGridView/API/GMGridViewLayoutStrategies.m | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/GMGridView/API/GMGridViewLayoutStrategies.h b/GMGridView/API/GMGridViewLayoutStrategies.h index 5b816b0..0ee5ee8 100644 --- a/GMGridView/API/GMGridViewLayoutStrategies.h +++ b/GMGridView/API/GMGridViewLayoutStrategies.h @@ -172,7 +172,7 @@ typedef enum { - (NSInteger)positionForItemAtColumn:(NSInteger)column row:(NSInteger)row page:(NSInteger)page; - (NSInteger)columnForItemAtPosition:(NSInteger)position; - (NSInteger)rowForItemAtPosition:(NSInteger)position; - +- (NSUInteger) pageForContentOffset:(CGPoint)offset; @end diff --git a/GMGridView/API/GMGridViewLayoutStrategies.m b/GMGridView/API/GMGridViewLayoutStrategies.m index 1a39dbc..23b79df 100644 --- a/GMGridView/API/GMGridViewLayoutStrategies.m +++ b/GMGridView/API/GMGridViewLayoutStrategies.m @@ -511,6 +511,10 @@ - (NSRange)rangeOfPositionsInBoundsFromOffset:(CGPoint)offset return NSMakeRange(firstPosition, (lastPosition - firstPosition)); } +- (NSUInteger) pageForContentOffset:(CGPoint)offset +{ + return floor(offset.x / self.gridBounds.size.width); +} @end From cbdc5f2f8b7c3fae68ce6701a5f2c05a697a6b1a Mon Sep 17 00:00:00 2001 From: Ran Tavory Date: Fri, 13 Jan 2012 12:05:54 +0200 Subject: [PATCH 12/13] Use algebra to calculate _numberOfItemsPerColumn, instead of a while loop --- GMGridView/API/GMGridViewLayoutStrategies.m | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/GMGridView/API/GMGridViewLayoutStrategies.m b/GMGridView/API/GMGridViewLayoutStrategies.m index de87975..c4ee884 100644 --- a/GMGridView/API/GMGridViewLayoutStrategies.m +++ b/GMGridView/API/GMGridViewLayoutStrategies.m @@ -269,12 +269,7 @@ - (void)rebaseWithItemCount:(NSInteger)count insideOfBounds:(CGRect)bounds bounds.size.width - self.minEdgeInsets.right - self.minEdgeInsets.left, bounds.size.height - self.minEdgeInsets.top - self.minEdgeInsets.bottom); - _numberOfItemsPerColumn = 1; - - while ((_numberOfItemsPerColumn + 1) * (self.itemSize.height + self.itemSpacing) - self.itemSpacing <= actualBounds.size.height) - { - _numberOfItemsPerColumn++; - } + _numberOfItemsPerColumn = floor((actualBounds.size.height + self.itemSpacing) / (self.itemSize.height + self.itemSpacing)); NSInteger numberOfColumns = ceil(self.itemCount / (1.0 * self.numberOfItemsPerColumn)); From a0e7f85a78beaf5fb2a559e9b0a8b011acb536ec Mon Sep 17 00:00:00 2001 From: Ran Tavory Date: Fri, 13 Jan 2012 15:32:56 +0200 Subject: [PATCH 13/13] Compute _numberOfItemsPerRow with algebra instead of a while loop. --- GMGridView/API/GMGridViewLayoutStrategies.m | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/GMGridView/API/GMGridViewLayoutStrategies.m b/GMGridView/API/GMGridViewLayoutStrategies.m index c4ee884..da84164 100644 --- a/GMGridView/API/GMGridViewLayoutStrategies.m +++ b/GMGridView/API/GMGridViewLayoutStrategies.m @@ -367,14 +367,9 @@ - (void)rebaseWithItemCount:(NSInteger)count insideOfBounds:(CGRect)bounds { [super rebaseWithItemCount:count insideOfBounds:bounds]; - _numberOfItemsPerRow = 1; - NSInteger gridContentMaxWidth = self.gridBounds.size.width - self.minEdgeInsets.right - self.minEdgeInsets.left; - while ((self.numberOfItemsPerRow + 1) * (self.itemSize.width + self.itemSpacing) - self.itemSpacing <= gridContentMaxWidth) - { - _numberOfItemsPerRow++; - } + _numberOfItemsPerRow = floor((gridContentMaxWidth + self.itemSpacing) / (self.itemSize.width + self.itemSpacing)); _numberOfItemsPerPage = _numberOfItemsPerRow * _numberOfItemsPerColumn; _numberOfPages = ceil(self.itemCount * 1.0 / self.numberOfItemsPerPage);