Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions GMGridView/GMGridView.h
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,11 @@ typedef enum
// Enable/Disable the shaking behavior of an item being moved
- (BOOL)GMGridView:(GMGridView *)gridView shouldAllowShakingBehaviorWhenMovingCell:(GMGridViewCell *)view atIndex:(NSInteger)index;

// Allow/Disallow moving of an item
- (BOOL)GMGridView:(GMGridView *)gridView shouldAllowMovingCell:(GMGridViewCell *)view atIndex:(NSInteger)index;
// Allow/Disallow placing item at index
- (BOOL)GMGridView:(GMGridView *)gridView shouldAllowMovingCell:(GMGridViewCell *)view toIndex:(NSInteger)index;

@end

//////////////////////////////////////////////////////////////
Expand Down
46 changes: 38 additions & 8 deletions GMGridView/GMGridView.m
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#import "GMGridViewCell+Extended.h"
#import "GMGridViewLayoutStrategies.h"
#import "UIGestureRecognizer+GMGridViewAdditions.h"
#import "UIView+GMGridViewAdditions.h"

static const NSInteger kTagOffset = 50;
static const CGFloat kDefaultAnimationDuration = 0.3;
Expand Down Expand Up @@ -60,6 +61,7 @@ @interface GMGridView () <UIGestureRecognizerDelegate, UIScrollViewDelegate>

// Moving (sorting) control vars
GMGridViewCell *_sortMovingItem;
CGRect _sortOriginalFrame;
NSInteger _sortFuturePosition;
BOOL _autoScrollActive;

Expand Down Expand Up @@ -250,6 +252,7 @@ - (void)commonInit
self.minEdgeInsets = UIEdgeInsetsMake(5, 5, 5, 5);
self.clipsToBounds = NO;

_sortOriginalFrame = CGRectZero;
_sortFuturePosition = GMGV_INVALID_POSITION;
_itemSize = CGSizeZero;
_centerGrid = YES;
Expand Down Expand Up @@ -500,7 +503,7 @@ - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
}
else if (gestureRecognizer == _longPressGesture)
{
valid = (self.sortingDelegate || self.enableEditOnLongPress) && !isScrolling && !self.isEditing;
valid = (self.sortingDelegate || self.enableEditOnLongPress) && !isScrolling;
}
else if (gestureRecognizer == _sortingPanGesture)
{
Expand Down Expand Up @@ -533,19 +536,18 @@ - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer

- (void)longPressGestureUpdated:(UILongPressGestureRecognizer *)longPressGesture
{
if (self.enableEditOnLongPress && !self.editing) {
if (self.enableEditOnLongPress && !self.editing) {
CGPoint locationTouch = [longPressGesture locationInView:self];
NSInteger position = [self.layoutStrategy itemPositionFromLocation:locationTouch];

if (position != GMGV_INVALID_POSITION)
if (position != GMGV_INVALID_POSITION)
{
if (!self.editing) {
self.editing = YES;
}
}
return;
}
switch (longPressGesture.state)
{
case UIGestureRecognizerStateBegan:
Expand All @@ -556,6 +558,14 @@ - (void)longPressGestureUpdated:(UILongPressGestureRecognizer *)longPressGesture

NSInteger position = [self.layoutStrategy itemPositionFromLocation:location];

// Ask the delegate if moving is permitted
if ([self.sortingDelegate respondsToSelector:@selector(GMGridView:shouldAllowMovingCell:atIndex:)])
{
GMGridViewCell *item = [self cellForItemAtIndex:position];
if (![self.sortingDelegate GMGridView:self shouldAllowMovingCell:item atIndex:position])
position = GMGV_INVALID_POSITION;
}

if (position != GMGV_INVALID_POSITION)
{
[self sortingMoveDidStartAtPoint:location];
Expand Down Expand Up @@ -607,7 +617,8 @@ - (void)sortingPanGestureUpdated:(UIPanGestureRecognizer *)panGesture
CGPoint offset = translation;
CGPoint locationInScroll = [panGesture locationInView:self];

_sortMovingItem.transform = CGAffineTransformMakeTranslation(offset.x, offset.y);
_sortMovingItem.frame = CGRectMake(_sortOriginalFrame.origin.x + offset.x, _sortOriginalFrame.origin.y + offset.y, _sortOriginalFrame.size.width, _sortOriginalFrame.size.height);

[self sortingMoveDidContinueToPoint:locationInScroll];

break;
Expand All @@ -623,8 +634,7 @@ - (void)sortingAutoScrollMovementCheck
{
CGPoint locationInMainView = [_sortingPanGesture locationInView:self];
locationInMainView = CGPointMake(locationInMainView.x - self.contentOffset.x,
locationInMainView.y -self.contentOffset.y
);
locationInMainView.y - self.contentOffset.y);


CGFloat threshhold = _itemSize.height;
Expand Down Expand Up @@ -706,6 +716,7 @@ - (void)sortingMoveDidStartAtPoint:(CGPoint)point
NSInteger position = [self.layoutStrategy itemPositionFromLocation:point];

GMGridViewCell *item = [self cellForItemAtIndex:position];
[item shakeStatus:NO];

[self bringSubviewToFront:item];
_sortMovingItem = item;
Expand All @@ -714,7 +725,13 @@ - (void)sortingMoveDidStartAtPoint:(CGPoint)point

[_sortMovingItem removeFromSuperview];
_sortMovingItem.frame = frameInMainView;
_sortOriginalFrame = frameInMainView;
[self.mainSuperView addSubview:_sortMovingItem];

[UIView animateWithDuration:0.2f
animations:^{
_sortMovingItem.transform = CGAffineTransformMakeScale(1.2f, 1.2f);
}];

_sortFuturePosition = _sortMovingItem.tag - kTagOffset;
_sortMovingItem.tag = 0;
Expand All @@ -737,6 +754,10 @@ - (void)sortingMoveDidStartAtPoint:(CGPoint)point
- (void)sortingMoveDidStopAtPoint:(CGPoint)point
{
[_sortMovingItem shake:NO];
[UIView animateWithDuration:0.2f
animations:^{
_sortMovingItem.transform = CGAffineTransformIdentity;
}];

_sortMovingItem.tag = _sortFuturePosition + kTagOffset;

Expand All @@ -763,6 +784,7 @@ - (void)sortingMoveDidStopAtPoint:(CGPoint)point
}

_sortMovingItem = nil;
_sortOriginalFrame = CGRectZero;
_sortFuturePosition = GMGV_INVALID_POSITION;

[self setSubviewsCacheAsInvalid];
Expand All @@ -775,6 +797,14 @@ - (void)sortingMoveDidContinueToPoint:(CGPoint)point
int position = [self.layoutStrategy itemPositionFromLocation:point];
int tag = position + kTagOffset;

// Ask the delegate if inserting item is permitted
if ([self.sortingDelegate respondsToSelector:@selector(GMGridView:shouldAllowMovingCell:toIndex:)])
{
GMGridViewCell *item = [self cellForItemAtIndex:position];
if (![self.sortingDelegate GMGridView:self shouldAllowMovingCell:item toIndex:position])
position = GMGV_INVALID_POSITION;
}

if (position != GMGV_INVALID_POSITION && position != _sortFuturePosition && position < _numberTotalItems)
{
BOOL positionTaken = NO;
Expand Down
7 changes: 5 additions & 2 deletions GMGridView/UIView+GMGridViewAdditions.m
Original file line number Diff line number Diff line change
Expand Up @@ -43,21 +43,24 @@ - (void)shakeStatus:(BOOL)enabled
{
if (enabled)
{
CGFloat rotation = 0.03;
CGFloat rotation = 0.02;

CABasicAnimation *shake = [CABasicAnimation animationWithKeyPath:@"transform"];
shake.duration = 0.13;
shake.duration = 0.09;
shake.autoreverses = YES;
shake.repeatCount = MAXFLOAT;
shake.removedOnCompletion = NO;
shake.fromValue = [NSValue valueWithCATransform3D:CATransform3DRotate(self.layer.transform,-rotation, 0.0 ,0.0 ,1.0)];
shake.toValue = [NSValue valueWithCATransform3D:CATransform3DRotate(self.layer.transform, rotation, 0.0 ,0.0 ,1.0)];

self.layer.shouldRasterize = YES;
self.layer.rasterizationScale = [[UIScreen mainScreen] scale];
[self.layer addAnimation:shake forKey:@"shakeAnimation"];
}
else
{
[self.layer removeAnimationForKey:@"shakeAnimation"];
self.layer.shouldRasterize = NO;
}
}

Expand Down