Permalink
Browse files

Better support for edgeInsets, better centering algorithm, horizontal…

… layout supported
  • Loading branch information...
1 parent 84a44f9 commit deef3499b2193585bac7fedb5c5ba6748431d528 @gmoledina committed Nov 1, 2011
View
3 GMGridView/API/GMGridView.h
@@ -59,8 +59,9 @@ typedef enum
// Customizing Options
@property (nonatomic) GMGridViewStyle style; // Default is GMGridViewStyleSwap
-@property (nonatomic) NSInteger itemPadding; // Default is 10
+@property (nonatomic) NSInteger itemSpacing; // Default is 10
@property (nonatomic) BOOL centerGrid; // Default is YES
+@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
View
83 GMGridView/API/GMGridView.m
@@ -101,6 +101,7 @@ - (BOOL)isInTransformingState;
- (void)exitFullSizePinchGestureUpdated:(UIPinchGestureRecognizer *)pinchGesture;
// Helpers & more
+- (void)recomputeSize;
- (void)relayoutItems;
- (NSArray *)itemSubviews;
- (GMGridViewCell *)itemSubViewForPosition:(NSInteger)position;
@@ -121,10 +122,11 @@ @implementation GMGridView
@synthesize sortingDelegate = _sortingDelegate, dataSource = _dataSource, transformDelegate = _transformDelegate;
@synthesize layoutStrategy = _layoutStrategy;
-@synthesize itemPadding = _itemPadding;
+@synthesize itemSpacing = _itemSpacing;
@synthesize style = _style;
@synthesize minimumPressDuration;
-@synthesize centerGrid;
+@synthesize centerGrid = _centerGrid;
+@synthesize minEdgeInsets = _minEdgeInsets;
@synthesize showFullSizeViewWithAlphaWhenTransforming;
@synthesize itemsSubviewsCacheIsValid = _itemsSubviewsCacheIsValid;
@@ -186,14 +188,14 @@ - (id)initWithFrame:(CGRect)frame
[_scrollView.panGestureRecognizer setMaximumNumberOfTouches:1];
[_scrollView.panGestureRecognizer requireGestureRecognizerToFail:_sortingPanGesture];
- self.layoutStrategy = [GMGridViewLayoutStrategyFactory strategyFromType:GMGridViewLayoutVertical];
+ //self.layoutStrategy = [GMGridViewLayoutStrategyFactory strategyFromType:GMGridViewLayoutVertical];
+ self.layoutStrategy = [GMGridViewLayoutStrategyFactory strategyFromType:GMGridViewLayoutHorizontal]; // Work in progress
- //self.layoutStrategy = [GMGridViewLayoutStrategyFactory strategyFromType:GMGridViewLayoutHorizontal]; // Work in progress
-
- self.itemPadding = 10;
+ self.itemSpacing = 10;
self.style = GMGridViewStyleSwap;
self.minimumPressDuration = 0.2;
self.showFullSizeViewWithAlphaWhenTransforming = YES;
+ self.minEdgeInsets = UIEdgeInsetsMake(5, 5, 5, 5);
_sortFuturePosition = GMGV_INVALID_POSITION;
_itemSize = CGSizeZero;
@@ -213,23 +215,7 @@ - (void)layoutSubviews
{
[super layoutSubviews];
- [self.layoutStrategy rebaseWithItemCount:_numberTotalItems havingSize:_itemSize andPadding:self.itemPadding insideOfBounds:self.bounds];
-
- _scrollView.contentSize = [self.layoutStrategy contentSize];
-
- if (self.centerGrid)
- {
- int extraSpace = (self.bounds.size.width - _scrollView.contentSize.width) / 2;
- if (extraSpace > 0)
- {
- _scrollView.contentInset = UIEdgeInsetsMake(0, extraSpace, 0, extraSpace);
- }
- }
- else
- {
- _scrollView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0);
- }
-
+ [self recomputeSize];
[self relayoutItems];
[_scrollView flashScrollIndicators];
@@ -252,9 +238,15 @@ - (void)setLayoutStrategy:(id<GMGridViewLayoutStrategy>)layoutStrategy
[self setNeedsLayout];
}
-- (void)setItemPadding:(NSInteger)itemPadding
+- (void)setItemSpacing:(NSInteger)itemSpacing
+{
+ _itemSpacing = itemSpacing;
+ [self setNeedsLayout];
+}
+
+- (void)setMinEdgeInsets:(UIEdgeInsets)minEdgeInsets
{
- _itemPadding = itemPadding;
+ _minEdgeInsets = minEdgeInsets;
[self setNeedsLayout];
}
@@ -469,6 +461,7 @@ - (void)sortingMoveDidStartAtPoint:(CGPoint)point
[self addSubview:_sortMovingItem];
_sortFuturePosition = _sortMovingItem.tag - kTagOffset;
+ _sortMovingItem.tag = 0;
[self.sortingDelegate GMGridView:self didStartMovingView:_sortMovingItem.contentView];
@@ -564,8 +557,7 @@ - (void)sortingMoveDidContinueToPoint:(CGPoint)point
{
if (_sortMovingItem)
{
- //UIView *v = [self itemSubViewForPosition:position];
- UIView *v = [_scrollView viewWithTag:tag];
+ UIView *v = [self itemSubViewForPosition:position];
v.tag = _sortFuturePosition + kTagOffset;
CGPoint origin = [self.layoutStrategy originForItemAtPosition:_sortFuturePosition];
@@ -974,6 +966,38 @@ - (void)updateIndexOfItem:(GMGridViewCell *)view toIndex:(NSInteger)index
}
}
+- (void)recomputeSize
+{
+ CGRect actualBounds = CGRectMake(0,
+ 0,
+ 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];
+
+ _scrollView.contentSize = [self.layoutStrategy contentSize];
+
+ if (self.centerGrid)
+ {
+ NSInteger widthSpace, heightSpace;
+ NSInteger top, left, bottom, right;
+
+ widthSpace = (self.bounds.size.width - _scrollView.contentSize.width) / 2;
+ heightSpace = (self.bounds.size.height - _scrollView.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;
+ }
+}
+
- (void)relayoutItems
{
[UIView animateWithDuration:kDefaultAnimationDuration
@@ -1023,7 +1047,7 @@ - (void)reloadData
_itemSize = CGSizeMake(width, height);
_numberTotalItems = numberItems;
- [self.layoutStrategy rebaseWithItemCount:_numberTotalItems havingSize:_itemSize andPadding:self.itemPadding insideOfBounds:self.bounds];
+ [self recomputeSize];
for (int i = 0; i < numberItems; i++)
{
@@ -1081,8 +1105,7 @@ - (void)insertObjectAtIndex:(NSInteger)index
_numberTotalItems++;
[_scrollView addSubview:cell];
- [self.layoutStrategy rebaseWithItemCount:_numberTotalItems havingSize:_itemSize andPadding:self.itemPadding insideOfBounds:self.bounds];
- _scrollView.contentSize = [self.layoutStrategy contentSize];
+ [self recomputeSize];
[_scrollView scrollRectToVisible:cell.frame animated:YES];
View
9 GMGridView/API/GMGridViewLayoutStrategies.h
@@ -58,7 +58,7 @@ typedef enum {
@protocol GMGridViewLayoutStrategy <NSObject>
// Setup
-- (void)rebaseWithItemCount:(NSInteger)count havingSize:(CGSize)itemSize andPadding:(NSInteger)padding insideOfBounds:(CGRect)bounds;
+- (void)rebaseWithItemCount:(NSInteger)count havingSize:(CGSize)itemSize andSpacing:(NSInteger)spacing insideOfBounds:(CGRect)bounds;
// Fetching the result
- (CGSize)contentSize;
@@ -76,17 +76,18 @@ typedef enum {
@interface GMGridViewLayoutStrategyBase : NSObject
{
@protected
- // All of these vars should be set in the rebase method
+
+ // All of these vars should be set in the rebase method of the child class
NSInteger _itemCount;
CGSize _itemSize;
- NSInteger _itemPadding;
+ NSInteger _itemSpacing;
CGRect _contentBounds;
CGSize _contentSize;
}
@property (nonatomic, readonly) NSInteger itemCount;
@property (nonatomic, readonly) CGSize itemSize;
-@property (nonatomic, readonly) NSInteger itemPadding;
+@property (nonatomic, readonly) NSInteger itemSpacing;
@property (nonatomic, readonly) CGRect contentBounds;
@property (nonatomic, readonly) CGSize contentSize;
View
46 GMGridView/API/GMGridViewLayoutStrategies.m
@@ -63,7 +63,7 @@ @implementation GMGridViewLayoutStrategyBase
@synthesize itemCount = _itemCount;
@synthesize itemSize = _itemSize;
-@synthesize itemPadding = _itemPadding;
+@synthesize itemSpacing = _itemSpacing;
@synthesize contentBounds = _contentBounds;
@synthesize contentSize = _contentSize;
@@ -79,24 +79,24 @@ @implementation GMGridViewLayoutVerticalStrategy
@synthesize numberOfItemsPerRow = _numberOfItemsPerRow;
-- (void)rebaseWithItemCount:(NSInteger)count havingSize:(CGSize)itemSize andPadding:(NSInteger)padding insideOfBounds:(CGRect)bounds
+- (void)rebaseWithItemCount:(NSInteger)count havingSize:(CGSize)itemSize andSpacing:(NSInteger)spacing insideOfBounds:(CGRect)bounds
{
_itemCount = count;
_itemSize = itemSize;
- _itemPadding = padding;
+ _itemSpacing = spacing;
_contentBounds = bounds;
_numberOfItemsPerRow = 1;
- while ((self.numberOfItemsPerRow + 1) * (self.itemSize.width + self.itemPadding) + self.itemPadding < self.contentBounds.size.width)
+ while ((self.numberOfItemsPerRow + 1) * (self.itemSize.width + self.itemSpacing) - self.itemSpacing < self.contentBounds.size.width)
{
_numberOfItemsPerRow++;
}
NSInteger numberOfRows = ceil(self.itemCount / (1.0 * self.numberOfItemsPerRow));
- _contentSize = CGSizeMake(ceil(self.numberOfItemsPerRow * (self.itemSize.width + self.itemPadding) + self.itemPadding),
- ceil(numberOfRows * (self.itemSize.height + self.itemPadding) + self.itemPadding));
+ _contentSize = CGSizeMake(ceil(MIN(self.itemCount, self.numberOfItemsPerRow) * (self.itemSize.width + self.itemSpacing)) - self.itemSpacing,
+ ceil(numberOfRows * (self.itemSize.height + self.itemSpacing)) - self.itemSpacing);
}
- (CGPoint)originForItemAtPosition:(NSInteger)position
@@ -108,17 +108,17 @@ - (CGPoint)originForItemAtPosition:(NSInteger)position
NSUInteger col = position % self.numberOfItemsPerRow;
NSUInteger row = position / self.numberOfItemsPerRow;
- origin = CGPointMake(col * (self.itemSize.width + self.itemPadding) + self.itemPadding,
- row * (self.itemSize.height + self.itemPadding) + self.itemPadding);
+ origin = CGPointMake(col * (self.itemSize.width + self.itemSpacing),
+ row * (self.itemSize.height + self.itemSpacing));
}
return origin;
}
- (NSInteger)itemPositionFromLocation:(CGPoint)location
{
- int col = (int) (location.x / (self.itemSize.width + self.itemPadding));
- int row = (int) (location.y / (self.itemSize.height + self.itemPadding));
+ int col = (int) (location.x / (self.itemSize.width + self.itemSpacing));
+ int row = (int) (location.y / (self.itemSize.height + self.itemSpacing));
int position = col + row * self.numberOfItemsPerRow;
@@ -131,8 +131,8 @@ - (NSInteger)itemPositionFromLocation:(CGPoint)location
CGPoint itemOrigin = [self originForItemAtPosition:position];
CGRect itemFrame = CGRectMake(itemOrigin.x,
itemOrigin.y,
- self.itemSize.width + self.itemPadding,
- self.itemSize.height + self.itemPadding);
+ self.itemSize.width,
+ self.itemSize.height);
if (!CGRectContainsPoint(itemFrame, location))
{
@@ -154,24 +154,24 @@ @implementation GMGridViewLayoutHorizontalStrategy
@synthesize numberOfItemsPerColumn = _numberOfItemsPerColumn;
-- (void)rebaseWithItemCount:(NSInteger)count havingSize:(CGSize)itemSize andPadding:(NSInteger)padding insideOfBounds:(CGRect)bounds
+- (void)rebaseWithItemCount:(NSInteger)count havingSize:(CGSize)itemSize andSpacing:(NSInteger)spacing insideOfBounds:(CGRect)bounds
{
_itemCount = count;
_itemSize = itemSize;
- _itemPadding = padding;
+ _itemSpacing = spacing;
_contentBounds = bounds;
_numberOfItemsPerColumn = 1;
- while ((_numberOfItemsPerColumn + 1) * (self.itemSize.height + self.itemPadding) + self.itemPadding < self.contentBounds.size.height)
+ while ((_numberOfItemsPerColumn + 1) * (self.itemSize.height + self.itemSpacing) - self.itemSpacing < self.contentBounds.size.height)
{
_numberOfItemsPerColumn++;
}
NSInteger numberOfColumns = ceil(self.itemCount / (1.0 * self.numberOfItemsPerColumn));
- _contentSize = CGSizeMake(ceil(numberOfColumns * (self.itemSize.width + self.itemPadding) + self.itemPadding),
- ceil(self.numberOfItemsPerColumn * (self.itemSize.height + self.itemPadding) + self.itemPadding));
+ _contentSize = CGSizeMake(ceil(numberOfColumns * (self.itemSize.width + self.itemSpacing)) - self.itemSpacing,
+ ceil(MIN(self.itemCount, self.numberOfItemsPerColumn) * (self.itemSize.height + self.itemSpacing)) - self.itemSpacing);
}
- (CGPoint)originForItemAtPosition:(NSInteger)position
@@ -183,17 +183,17 @@ - (CGPoint)originForItemAtPosition:(NSInteger)position
NSUInteger col = position / self.numberOfItemsPerColumn;
NSUInteger row = position % self.numberOfItemsPerColumn;
- origin = CGPointMake(col * (self.itemSize.width + self.itemPadding) + self.itemPadding,
- row * (self.itemSize.height + self.itemPadding) + self.itemPadding);
+ origin = CGPointMake(col * (self.itemSize.width + self.itemSpacing),
+ row * (self.itemSize.height + self.itemSpacing));
}
return origin;
}
- (NSInteger)itemPositionFromLocation:(CGPoint)location
{
- int col = (int) (location.x / (self.itemSize.width + self.itemPadding));
- int row = (int) (location.y / (self.itemSize.height + self.itemPadding));
+ int col = (int) (location.x / (self.itemSize.width + self.itemSpacing));
+ int row = (int) (location.y / (self.itemSize.height + self.itemSpacing));
int position = row + col * self.numberOfItemsPerColumn;
@@ -206,8 +206,8 @@ - (NSInteger)itemPositionFromLocation:(CGPoint)location
CGPoint itemOrigin = [self originForItemAtPosition:position];
CGRect itemFrame = CGRectMake(itemOrigin.x,
itemOrigin.y,
- self.itemSize.width + self.itemPadding,
- self.itemSize.height + self.itemPadding);
+ self.itemSize.width,
+ self.itemSize.height);
if (!CGRectContainsPoint(itemFrame, location))
{
View
20 GMGridView/API/UIGestureRecognizer+GMGridViewAdditions.h
@@ -5,6 +5,26 @@
// Created by Gulam Moledina on 11-10-30.
// Copyright (c) 2011 GMoledina.ca. All rights reserved.
//
+// Latest code can be found on GitHub: https://github.com/gmoledina/GMGridView
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
#import <UIKit/UIKit.h>
View
20 GMGridView/API/UIGestureRecognizer+GMGridViewAdditions.m
@@ -5,6 +5,26 @@
// Created by Gulam Moledina on 11-10-30.
// Copyright (c) 2011 GMoledina.ca. All rights reserved.
//
+// Latest code can be found on GitHub: https://github.com/gmoledina/GMGridView
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
#import "UIGestureRecognizer+GMGridViewAdditions.h"
View
4 GMGridView/ViewController.m
@@ -10,7 +10,7 @@
#import "GMGridView.h"
#import <QuartzCore/QuartzCore.h>
-#define NUMBER_ITEMS_ON_LOAD 250
+#define NUMBER_ITEMS_ON_LOAD 25
//////////////////////////////////////////////////////////////
#pragma mark -
@@ -103,7 +103,7 @@ - (void)loadView
GMGridView *gmGridView = [[GMGridView alloc] initWithFrame:self.view.bounds];
gmGridView.style = GMGridViewStyleSwap;
gmGridView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
- gmGridView.itemPadding = _itemPadding;
+ gmGridView.itemSpacing = _itemPadding;
gmGridView.centerGrid = YES;
gmGridView.backgroundColor = [UIColor whiteColor];
[self.view addSubview:gmGridView];

0 comments on commit deef349

Please sign in to comment.