Skip to content

Commit

Permalink
Moved more layout logic to layout strategy classes
Browse files Browse the repository at this point in the history
  • Loading branch information
gmoledina committed Dec 11, 2011
1 parent c54c7cf commit 4161cdd
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 55 deletions.
2 changes: 2 additions & 0 deletions GMGridView.xcodeproj/project.pbxproj
Expand Up @@ -310,6 +310,7 @@
GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "GMGridView/GMGridView-Prefix.pch"; GCC_PREFIX_HEADER = "GMGridView/GMGridView-Prefix.pch";
INFOPLIST_FILE = "GMGridView/GMGridView-Info.plist"; INFOPLIST_FILE = "GMGridView/GMGridView-Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 5.0;
PRODUCT_NAME = GMGridView; PRODUCT_NAME = GMGridView;
WRAPPER_EXTENSION = app; WRAPPER_EXTENSION = app;
}; };
Expand All @@ -321,6 +322,7 @@
GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "GMGridView/GMGridView-Prefix.pch"; GCC_PREFIX_HEADER = "GMGridView/GMGridView-Prefix.pch";
INFOPLIST_FILE = "GMGridView/GMGridView-Info.plist"; INFOPLIST_FILE = "GMGridView/GMGridView-Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 5.0;
PRODUCT_NAME = GMGridView; PRODUCT_NAME = GMGridView;
WRAPPER_EXTENSION = app; WRAPPER_EXTENSION = app;
}; };
Expand Down
29 changes: 3 additions & 26 deletions GMGridView/API/GMGridView.m
Expand Up @@ -249,6 +249,7 @@ - (void)layoutSubviews


[self recomputeSize]; [self recomputeSize];
[self relayoutItems]; [self relayoutItems];
[self loadRequiredItems];


[_scrollView flashScrollIndicators]; [_scrollView flashScrollIndicators];
} }
Expand Down Expand Up @@ -1067,35 +1068,11 @@ - (NSInteger)positionForItemSubview:(GMGridViewCell *)view


- (void)recomputeSize - (void)recomputeSize
{ {
CGRect actualBounds = CGRectMake(0, [self.layoutStrategy setupItemSize:_itemSize andItemSpacing:self.itemSpacing withMinEdgeInsets:self.minEdgeInsets andCenteredGrid:self.centerGrid];
0, [self.layoutStrategy rebaseWithItemCount:_numberTotalItems insideOfBounds:self.bounds];
self.bounds.size.width - self.minEdgeInsets.right - self.minEdgeInsets.left,
self.bounds.size.height - self.minEdgeInsets.top - self.minEdgeInsets.bottom);

[self.layoutStrategy rebaseWithItemCount:_numberTotalItems havingSize:_itemSize andSpacing:self.itemSpacing insideOfBounds:actualBounds];


CGSize contentSize = [self.layoutStrategy contentSize]; CGSize contentSize = [self.layoutStrategy contentSize];


if (self.centerGrid)
{
NSInteger widthSpace, heightSpace;
NSInteger top, left, bottom, right;

widthSpace = (self.bounds.size.width - contentSize.width) / 2;
heightSpace = (self.bounds.size.height - contentSize.height) / 2;

left = (widthSpace < self.minEdgeInsets.left) ? self.minEdgeInsets.left : widthSpace;
right = (widthSpace < self.minEdgeInsets.right) ? self.minEdgeInsets.right : widthSpace;
top = (heightSpace < self.minEdgeInsets.top) ? self.minEdgeInsets.top : heightSpace;
bottom = (heightSpace < self.minEdgeInsets.bottom) ? self.minEdgeInsets.bottom : heightSpace;

_scrollView.contentInset = UIEdgeInsetsMake(top, left, bottom, right);
}
else
{
_scrollView.contentInset = self.minEdgeInsets;
}

_minPossibleContentOffset = CGPointMake(-1 * (_scrollView.contentInset.left), _minPossibleContentOffset = CGPointMake(-1 * (_scrollView.contentInset.left),
-1 * (_scrollView.contentInset.top)); -1 * (_scrollView.contentInset.top));
_maxPossibleContentOffset = CGPointMake(contentSize.width - _scrollView.bounds.size.width + _scrollView.contentInset.right, _maxPossibleContentOffset = CGPointMake(contentSize.width - _scrollView.bounds.size.width + _scrollView.contentInset.right,
Expand Down
31 changes: 26 additions & 5 deletions GMGridView/API/GMGridViewLayoutStrategies.h
Expand Up @@ -60,9 +60,12 @@ typedef enum {
- (GMGridViewLayoutStrategyType)type; - (GMGridViewLayoutStrategyType)type;


// Setup // Setup
- (void)rebaseWithItemCount:(NSInteger)count havingSize:(CGSize)itemSize andSpacing:(NSInteger)spacing insideOfBounds:(CGRect)bounds; - (void)setupItemSize:(CGSize)itemSize andItemSpacing:(NSInteger)spacing withMinEdgeInsets:(UIEdgeInsets)edgeInsets andCenteredGrid:(BOOL)centered;


// Fetching the result // Recomputing
- (void)rebaseWithItemCount:(NSInteger)count insideOfBounds:(CGRect)bounds;

// Fetching the results
- (CGSize)contentSize; - (CGSize)contentSize;
- (CGPoint)originForItemAtPosition:(NSInteger)position; - (CGPoint)originForItemAtPosition:(NSInteger)position;
- (NSInteger)itemPositionFromLocation:(CGPoint)location; - (NSInteger)itemPositionFromLocation:(CGPoint)location;
Expand All @@ -82,21 +85,39 @@ typedef enum {
// All of these vars should be set in the init method // All of these vars should be set in the init method
GMGridViewLayoutStrategyType _type; GMGridViewLayoutStrategyType _type;


// All of these vars should be set in the rebase method of the child class // All of these vars should be set in the setup method of the child class
NSInteger _itemCount;
CGSize _itemSize; CGSize _itemSize;
NSInteger _itemSpacing; NSInteger _itemSpacing;
UIEdgeInsets _minEdgeInsets;
BOOL _centeredGrid;

// All of these vars should be set in the rebase method of the child class
NSInteger _itemCount;
UIEdgeInsets _edgeInsets;
CGRect _gridBounds;
CGRect _contentBounds; CGRect _contentBounds;
CGSize _contentSize; CGSize _contentSize;
} }


@property (nonatomic, readonly) GMGridViewLayoutStrategyType type; @property (nonatomic, readonly) GMGridViewLayoutStrategyType type;
@property (nonatomic, readonly) NSInteger itemCount;
@property (nonatomic, readonly) CGSize itemSize; @property (nonatomic, readonly) CGSize itemSize;
@property (nonatomic, readonly) NSInteger itemSpacing; @property (nonatomic, readonly) NSInteger itemSpacing;
@property (nonatomic, readonly) UIEdgeInsets minEdgeInsets;
@property (nonatomic, readonly) BOOL centeredGrid;

@property (nonatomic, readonly) NSInteger itemCount;
@property (nonatomic, readonly) UIEdgeInsets edgeInsets;
@property (nonatomic, readonly) CGRect gridBounds;
@property (nonatomic, readonly) CGRect contentBounds; @property (nonatomic, readonly) CGRect contentBounds;
@property (nonatomic, readonly) CGSize contentSize; @property (nonatomic, readonly) CGSize contentSize;


// Protocol methods implemented in base class
- (void)setupItemSize:(CGSize)itemSize andItemSpacing:(NSInteger)spacing withMinEdgeInsets:(UIEdgeInsets)edgeInsets andCenteredGrid:(BOOL)centered;

// Helpers
- (void)setEdgeAndContentSizeFromAbsoluteContentSize:(CGSize)actualContentSize;

@end @end


////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////
Expand Down
117 changes: 93 additions & 24 deletions GMGridView/API/GMGridViewLayoutStrategies.m
Expand Up @@ -64,12 +64,53 @@ @implementation GMGridViewLayoutStrategyFactory
@implementation GMGridViewLayoutStrategyBase @implementation GMGridViewLayoutStrategyBase


@synthesize type = _type; @synthesize type = _type;
@synthesize itemCount = _itemCount;
@synthesize itemSize = _itemSize; @synthesize itemSize = _itemSize;
@synthesize itemSpacing = _itemSpacing; @synthesize itemSpacing = _itemSpacing;
@synthesize minEdgeInsets = _minEdgeInsets;
@synthesize centeredGrid = _centeredGrid;

@synthesize itemCount = _itemCount;
@synthesize edgeInsets = _edgeInsets;
@synthesize gridBounds = _gridBounds;
@synthesize contentBounds = _contentBounds; @synthesize contentBounds = _contentBounds;
@synthesize contentSize = _contentSize; @synthesize contentSize = _contentSize;



- (void)setupItemSize:(CGSize)itemSize andItemSpacing:(NSInteger)spacing withMinEdgeInsets:(UIEdgeInsets)edgeInsets andCenteredGrid:(BOOL)centered
{
_itemSize = itemSize;
_itemSpacing = spacing;
_minEdgeInsets = edgeInsets;
_centeredGrid = centered;
}

- (void)setEdgeAndContentSizeFromAbsoluteContentSize:(CGSize)actualContentSize
{
if (self.centeredGrid)
{
NSInteger widthSpace, heightSpace;
NSInteger top, left, bottom, right;

widthSpace = floor((self.gridBounds.size.width - actualContentSize.width) / 2.0);
heightSpace = floor((self.gridBounds.size.height - actualContentSize.height) / 2.0);

left = MAX(widthSpace, self.minEdgeInsets.left);
right = MAX(widthSpace, self.minEdgeInsets.right);
top = MAX(heightSpace, self.minEdgeInsets.top);
bottom = MAX(heightSpace, self.minEdgeInsets.bottom);

_edgeInsets = UIEdgeInsetsMake(top, left, bottom, right);
}
else
{
_edgeInsets = self.minEdgeInsets;
}


_contentSize = actualContentSize;
}

@end @end




Expand All @@ -93,24 +134,36 @@ - (id)init
return self; return self;
} }


- (void)rebaseWithItemCount:(NSInteger)count havingSize:(CGSize)itemSize andSpacing:(NSInteger)spacing insideOfBounds:(CGRect)bounds - (void)rebaseWithItemCount:(NSInteger)count insideOfBounds:(CGRect)bounds
{ {
_itemCount = count; _itemCount = count;
_itemSize = itemSize; _gridBounds = bounds;
_itemSpacing = spacing;
_contentBounds = bounds; CGRect actualBounds = CGRectMake(0,
0,
bounds.size.width - self.minEdgeInsets.right - self.minEdgeInsets.left,
bounds.size.height - self.minEdgeInsets.top - self.minEdgeInsets.bottom);



_numberOfItemsPerRow = 1; _numberOfItemsPerRow = 1;


while ((self.numberOfItemsPerRow + 1) * (self.itemSize.width + self.itemSpacing) - self.itemSpacing < self.contentBounds.size.width) while ((self.numberOfItemsPerRow + 1) * (self.itemSize.width + self.itemSpacing) - self.itemSpacing < actualBounds.size.width)
{ {
_numberOfItemsPerRow++; _numberOfItemsPerRow++;
} }


NSInteger numberOfRows = ceil(self.itemCount / (1.0 * self.numberOfItemsPerRow)); NSInteger numberOfRows = ceil(self.itemCount / (1.0 * self.numberOfItemsPerRow));


_contentSize = CGSizeMake(ceil(MIN(self.itemCount, self.numberOfItemsPerRow) * (self.itemSize.width + self.itemSpacing)) - self.itemSpacing, CGSize actualContentSize = CGSizeMake(ceil(MIN(self.itemCount, self.numberOfItemsPerRow) * (self.itemSize.width + self.itemSpacing)) - self.itemSpacing,
ceil(numberOfRows * (self.itemSize.height + self.itemSpacing)) - self.itemSpacing); ceil(numberOfRows * (self.itemSize.height + self.itemSpacing)) - self.itemSpacing);

[self setEdgeAndContentSizeFromAbsoluteContentSize:actualContentSize];

_contentBounds = CGRectMake(actualBounds.origin.x + _edgeInsets.left,
actualBounds.origin.y + _edgeInsets.top,
actualBounds.size.width -_edgeInsets.left - _edgeInsets.right,
actualBounds.size.height - _edgeInsets.top - _edgeInsets.bottom);

} }


- (CGPoint)originForItemAtPosition:(NSInteger)position - (CGPoint)originForItemAtPosition:(NSInteger)position
Expand All @@ -122,17 +175,20 @@ - (CGPoint)originForItemAtPosition:(NSInteger)position
NSUInteger col = position % self.numberOfItemsPerRow; NSUInteger col = position % self.numberOfItemsPerRow;
NSUInteger row = position / self.numberOfItemsPerRow; NSUInteger row = position / self.numberOfItemsPerRow;


origin = CGPointMake(col * (self.itemSize.width + self.itemSpacing), origin = CGPointMake(col * (self.itemSize.width + self.itemSpacing) + self.edgeInsets.left,
row * (self.itemSize.height + self.itemSpacing)); row * (self.itemSize.height + self.itemSpacing) + self.edgeInsets.top);
} }


return origin; return origin;
} }


- (NSInteger)itemPositionFromLocation:(CGPoint)location - (NSInteger)itemPositionFromLocation:(CGPoint)location
{ {
int col = (int) (location.x / (self.itemSize.width + self.itemSpacing)); CGPoint relativeLocation = CGPointMake(location.x - self.edgeInsets.left,
int row = (int) (location.y / (self.itemSize.height + self.itemSpacing)); location.y - self.edgeInsets.top);

int col = (int) (relativeLocation.x / (self.itemSize.width + self.itemSpacing));
int row = (int) (relativeLocation.y / (self.itemSize.height + self.itemSpacing));


int position = col + row * self.numberOfItemsPerRow; int position = col + row * self.numberOfItemsPerRow;


Expand Down Expand Up @@ -196,24 +252,34 @@ - (id)init
return self; return self;
} }


- (void)rebaseWithItemCount:(NSInteger)count havingSize:(CGSize)itemSize andSpacing:(NSInteger)spacing insideOfBounds:(CGRect)bounds - (void)rebaseWithItemCount:(NSInteger)count insideOfBounds:(CGRect)bounds
{ {
_itemCount = count; _itemCount = count;
_itemSize = itemSize; _gridBounds = bounds;
_itemSpacing = spacing;
_contentBounds = bounds; CGRect actualBounds = CGRectMake(0,
0,
bounds.size.width - self.minEdgeInsets.right - self.minEdgeInsets.left,
bounds.size.height - self.minEdgeInsets.top - self.minEdgeInsets.bottom);


_numberOfItemsPerColumn = 1; _numberOfItemsPerColumn = 1;


while ((_numberOfItemsPerColumn + 1) * (self.itemSize.height + self.itemSpacing) - self.itemSpacing < self.contentBounds.size.height) while ((_numberOfItemsPerColumn + 1) * (self.itemSize.height + self.itemSpacing) - self.itemSpacing < actualBounds.size.height)
{ {
_numberOfItemsPerColumn++; _numberOfItemsPerColumn++;
} }


NSInteger numberOfColumns = ceil(self.itemCount / (1.0 * self.numberOfItemsPerColumn)); NSInteger numberOfColumns = ceil(self.itemCount / (1.0 * self.numberOfItemsPerColumn));


_contentSize = CGSizeMake(ceil(numberOfColumns * (self.itemSize.width + self.itemSpacing)) - self.itemSpacing, CGSize actualContentSize = CGSizeMake(ceil(numberOfColumns * (self.itemSize.width + self.itemSpacing)) - self.itemSpacing,
ceil(MIN(self.itemCount, self.numberOfItemsPerColumn) * (self.itemSize.height + self.itemSpacing)) - self.itemSpacing); ceil(MIN(self.itemCount, self.numberOfItemsPerColumn) * (self.itemSize.height + self.itemSpacing)) - self.itemSpacing);

[self setEdgeAndContentSizeFromAbsoluteContentSize:actualContentSize];

_contentBounds = CGRectMake(actualBounds.origin.x + _edgeInsets.left,
actualBounds.origin.y + _edgeInsets.top,
actualBounds.size.width -_edgeInsets.left - _edgeInsets.right,
actualBounds.size.height - _edgeInsets.top - _edgeInsets.bottom);
} }


- (CGPoint)originForItemAtPosition:(NSInteger)position - (CGPoint)originForItemAtPosition:(NSInteger)position
Expand All @@ -225,17 +291,20 @@ - (CGPoint)originForItemAtPosition:(NSInteger)position
NSUInteger col = position / self.numberOfItemsPerColumn; NSUInteger col = position / self.numberOfItemsPerColumn;
NSUInteger row = position % self.numberOfItemsPerColumn; NSUInteger row = position % self.numberOfItemsPerColumn;


origin = CGPointMake(col * (self.itemSize.width + self.itemSpacing), origin = CGPointMake(col * (self.itemSize.width + self.itemSpacing) + self.edgeInsets.left,
row * (self.itemSize.height + self.itemSpacing)); row * (self.itemSize.height + self.itemSpacing) + self.edgeInsets.top);
} }


return origin; return origin;
} }


- (NSInteger)itemPositionFromLocation:(CGPoint)location - (NSInteger)itemPositionFromLocation:(CGPoint)location
{ {
int col = (int) (location.x / (self.itemSize.width + self.itemSpacing)); CGPoint relativeLocation = CGPointMake(location.x - self.edgeInsets.left,
int row = (int) (location.y / (self.itemSize.height + self.itemSpacing)); location.y - self.edgeInsets.top);

int col = (int) (relativeLocation.x / (self.itemSize.width + self.itemSpacing));
int row = (int) (relativeLocation.y / (self.itemSize.height + self.itemSpacing));


int position = row + col * self.numberOfItemsPerColumn; int position = row + col * self.numberOfItemsPerColumn;


Expand Down

0 comments on commit 4161cdd

Please sign in to comment.