diff --git a/GMGridView/GMGridView.h b/GMGridView/GMGridView.h index 6dff876..7282e1d 100644 --- a/GMGridView/GMGridView.h +++ b/GMGridView/GMGridView.h @@ -84,6 +84,8 @@ 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 view wont be scrollable @property (nonatomic) BOOL showFullSizeViewWithAlphaWhenTransforming; // Default is YES - not working right now +@property (nonatomic) BOOL enableEditOnLongPress; // Default is NO +@property (nonatomic) BOOL disableEditOnEmptySpaceTap; // Default is NO @property (nonatomic, readonly) UIScrollView *scrollView __attribute__((deprecated)); // The grid now inherits directly from UIScrollView @@ -147,6 +149,8 @@ typedef enum // This method wont delete the cell automatically. Call the delete method of the gridView when appropriate. - (void)GMGridView:(GMGridView *)gridView processDeleteActionForItemAtIndex:(NSInteger)index; +- (void)GMGridView:(GMGridView *)gridView changedEdit:(BOOL)edit; + @end diff --git a/GMGridView/GMGridView.m b/GMGridView/GMGridView.m index 0dbe346..c362c29 100644 --- a/GMGridView/GMGridView.m +++ b/GMGridView/GMGridView.m @@ -45,7 +45,7 @@ @interface GMGridView () { // Sorting Gestures UIPanGestureRecognizer *_sortingPanGesture; - UILongPressGestureRecognizer *_sortingLongPressGesture; + UILongPressGestureRecognizer *_longPressGesture; // Moving gestures UIPinchGestureRecognizer *_pinchGesture; @@ -86,7 +86,7 @@ - (void)commonInit; // Gestures - (void)sortingPanGestureUpdated:(UIPanGestureRecognizer *)panGesture; -- (void)sortingLongPressGestureUpdated:(UILongPressGestureRecognizer *)longPressGesture; +- (void)longPressGestureUpdated:(UILongPressGestureRecognizer *)longPressGesture; - (void)tapGestureUpdated:(UITapGestureRecognizer *)tapGesture; - (void)panGestureUpdated:(UIPanGestureRecognizer *)panGesture; - (void)pinchGestureUpdated:(UIPinchGestureRecognizer *)pinchGesture; @@ -144,6 +144,8 @@ @implementation GMGridView @synthesize minEdgeInsets = _minEdgeInsets; @synthesize showFullSizeViewWithAlphaWhenTransforming; @synthesize editing = _editing; +@synthesize enableEditOnLongPress; +@synthesize disableEditOnEmptySpaceTap; @synthesize itemsSubviewsCacheIsValid = _itemsSubviewsCacheIsValid; @synthesize itemSubviewsCache; @@ -185,6 +187,7 @@ - (void)commonInit _tapGesture.delegate = self; _tapGesture.numberOfTapsRequired = 1; _tapGesture.numberOfTouchesRequired = 1; + _tapGesture.cancelsTouchesInView = NO; [self addGestureRecognizer:_tapGesture]; ///////////////////////////// @@ -210,10 +213,11 @@ - (void)commonInit _sortingPanGesture.delegate = self; [self addGestureRecognizer:_sortingPanGesture]; - _sortingLongPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(sortingLongPressGestureUpdated:)]; - _sortingLongPressGesture.numberOfTouchesRequired = 1; - _sortingLongPressGesture.delegate = self; - [self addGestureRecognizer:_sortingLongPressGesture]; + _longPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressGestureUpdated:)]; + _longPressGesture.numberOfTouchesRequired = 1; + _longPressGesture.delegate = self; + _longPressGesture.cancelsTouchesInView = NO; + [self addGestureRecognizer:_longPressGesture]; //////////////////////// // Gesture dependencies @@ -415,17 +419,21 @@ - (void)setMinEdgeInsets:(UIEdgeInsets)minEdgeInsets - (void)setMinimumPressDuration:(CFTimeInterval)duration { - _sortingLongPressGesture.minimumPressDuration = duration; + _longPressGesture.minimumPressDuration = duration; } - (CFTimeInterval)minimumPressDuration { - return _sortingLongPressGesture.minimumPressDuration; + return _longPressGesture.minimumPressDuration; } - (void)setEditing:(BOOL)editing { [self setEditing:editing animated:NO]; + + if ([self.actionDelegate respondsToSelector:@selector(GMGridView:changedEdit:)]) { + [self.actionDelegate GMGridView:self changedEdit:editing]; + } } - (void)setEditing:(BOOL)editing animated:(BOOL)animated @@ -481,15 +489,22 @@ - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer if (gestureRecognizer == _tapGesture) { - valid = !isScrolling && !self.isEditing && ![_sortingLongPressGesture hasRecognizedValidGesture]; + if (self.editing && self.disableEditOnEmptySpaceTap) { + CGPoint locationTouch = [_tapGesture locationInView:self]; + NSInteger position = [self.layoutStrategy itemPositionFromLocation:locationTouch]; + + valid = (position == GMGV_INVALID_POSITION); + } else { + valid = !isScrolling && !self.isEditing && ![_longPressGesture hasRecognizedValidGesture]; + } } - else if (gestureRecognizer == _sortingLongPressGesture) + else if (gestureRecognizer == _longPressGesture) { - valid = !isScrolling && !self.isEditing && (self.sortingDelegate != nil); + valid = (self.sortingDelegate || self.enableEditOnLongPress) && !isScrolling && !self.isEditing; } else if (gestureRecognizer == _sortingPanGesture) { - valid = (_sortMovingItem != nil && [_sortingLongPressGesture hasRecognizedValidGesture]); + valid = (_sortMovingItem != nil && [_longPressGesture hasRecognizedValidGesture]); } else if(gestureRecognizer == _rotationGesture || gestureRecognizer == _pinchGesture || gestureRecognizer == _panGesture) { @@ -516,8 +531,21 @@ - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer #pragma mark Sorting gestures & logic ////////////////////////////////////////////////////////////// -- (void)sortingLongPressGestureUpdated:(UILongPressGestureRecognizer *)longPressGesture +- (void)longPressGestureUpdated:(UILongPressGestureRecognizer *)longPressGesture { + if (self.enableEditOnLongPress && !self.editing) { + CGPoint locationTouch = [longPressGesture locationInView:self]; + NSInteger position = [self.layoutStrategy itemPositionFromLocation:locationTouch]; + + if (position != GMGV_INVALID_POSITION) + { + if (!self.editing) { + self.editing = YES; + } + } + return; + } + switch (longPressGesture.state) { case UIGestureRecognizerStateBegan: @@ -1117,11 +1145,21 @@ - (void)tapGestureUpdated:(UITapGestureRecognizer *)tapGesture if (position != GMGV_INVALID_POSITION) { - [self.actionDelegate GMGridView:self didTapOnItemAtIndex:position]; + if (!self.editing) { + [self cellForItemAtIndex:position].highlighted = NO; + [self.actionDelegate GMGridView:self didTapOnItemAtIndex:position]; + } } - else if([self.actionDelegate respondsToSelector:@selector(GMGridViewDidTapOnEmptySpace:)]) - { - [self.actionDelegate GMGridViewDidTapOnEmptySpace:self]; + else + { + if([self.actionDelegate respondsToSelector:@selector(GMGridViewDidTapOnEmptySpace:)]) + { + [self.actionDelegate GMGridViewDidTapOnEmptySpace:self]; + } + + if (self.disableEditOnEmptySpaceTap) { + self.editing = NO; + } } } @@ -1594,14 +1632,14 @@ - (void)insertObjectAtIndex:(NSInteger)index withAnimation:(GMGridViewItemAnimat oldView.tag = oldView.tag + 1; } - if (animation & GMGridViewItemAnimationFade) { - cell.alpha = 0; - [UIView beginAnimations:nil context:NULL]; - [UIView setAnimationDelay:kDefaultAnimationDuration]; - [UIView setAnimationDuration:kDefaultAnimationDuration]; - cell.alpha = 1.0; - [UIView commitAnimations]; - } + if (animation & GMGridViewItemAnimationFade) { + cell.alpha = 0; + [UIView beginAnimations:nil context:NULL]; + [UIView setAnimationDelay:kDefaultAnimationDuration]; + [UIView setAnimationDuration:kDefaultAnimationDuration]; + cell.alpha = 1.0; + [UIView commitAnimations]; + } [self addSubview:cell]; } diff --git a/GMGridView/GMGridViewCell.h b/GMGridView/GMGridViewCell.h index 79adab1..c69028d 100644 --- a/GMGridView/GMGridViewCell.h +++ b/GMGridView/GMGridViewCell.h @@ -35,6 +35,7 @@ @property (nonatomic, strong) UIImage *deleteButtonIcon; // Delete button image @property (nonatomic) CGPoint deleteButtonOffset; // Delete button offset relative to the origin @property (nonatomic, strong) NSString *reuseIdentifier; +@property (nonatomic, getter=isHighlighted) BOOL highlighted; /// Override to release custom data before cell is reused. - (void)prepareForReuse; diff --git a/GMGridView/GMGridViewCell.m b/GMGridView/GMGridViewCell.m index cb5504a..67e5013 100644 --- a/GMGridView/GMGridViewCell.m +++ b/GMGridView/GMGridViewCell.m @@ -57,6 +57,7 @@ @implementation GMGridViewCell @synthesize deleteButtonIcon = _deleteButtonIcon; @synthesize deleteButtonOffset; @synthesize reuseIdentifier; +@synthesize highlighted; ////////////////////////////////////////////////////////////// #pragma mark Constructors @@ -77,7 +78,6 @@ - (id)initWithFrame:(CGRect)frame UIButton *deleteButton = [UIButton buttonWithType:UIButtonTypeCustom]; self.deleteButton = deleteButton; [self.deleteButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; - self.deleteButton.showsTouchWhenHighlighted = YES; self.deleteButtonIcon = nil; self.deleteButtonOffset = CGPointMake(-5, -5); self.deleteButton.alpha = 0; @@ -106,6 +106,21 @@ - (void)layoutSubviews } } +- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event +{ + self.highlighted = YES; +} + +- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event +{ + self.highlighted = NO; +} + +- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event +{ + self.highlighted = NO; +} + ////////////////////////////////////////////////////////////// #pragma mark Setters / getters ////////////////////////////////////////////////////////////// @@ -183,7 +198,7 @@ - (void)setEditing:(BOOL)editing animated:(BOOL)animated }else { self.deleteButton.alpha = editing ? 1.f : 0.f; } - + self.contentView.userInteractionEnabled = !editing; [self shakeStatus:editing]; } @@ -235,6 +250,18 @@ - (UIImage *)deleteButtonIcon return [self.deleteButton currentImage]; } + +- (void)setHighlighted:(BOOL)aHighlighted { + highlighted = aHighlighted; + + [self.contentView recursiveEnumerateSubviewsUsingBlock:^(UIView *view, BOOL *stop) { + if ([view respondsToSelector:@selector(setHighlighted:)]) { + [(UIControl*)view setHighlighted:highlighted]; + } + }]; +} + + ////////////////////////////////////////////////////////////// #pragma mark Private methods ////////////////////////////////////////////////////////////// @@ -292,7 +319,7 @@ - (void)switchToFullSizeMode:(BOOL)fullSizeEnabled completion:^(BOOL finished){ [self setNeedsLayout]; } - ]; + ]; } else { diff --git a/GMGridView/UIView+GMGridViewAdditions.h b/GMGridView/UIView+GMGridViewAdditions.h index de78945..6bd5d4d 100644 --- a/GMGridView/UIView+GMGridViewAdditions.h +++ b/GMGridView/UIView+GMGridViewAdditions.h @@ -32,5 +32,5 @@ @interface UIView (GMGridViewAdditions) - (void)shakeStatus:(BOOL)enabled; - +- (void)recursiveEnumerateSubviewsUsingBlock:(void (^)(UIView *view, BOOL *stop))block; @end diff --git a/GMGridView/UIView+GMGridViewAdditions.m b/GMGridView/UIView+GMGridViewAdditions.m index b5664af..22bec53 100644 --- a/GMGridView/UIView+GMGridViewAdditions.m +++ b/GMGridView/UIView+GMGridViewAdditions.m @@ -61,4 +61,17 @@ - (void)shakeStatus:(BOOL)enabled } } +- (void)recursiveEnumerateSubviewsUsingBlock:(void (^)(UIView *view, BOOL *stop))block { + if (self.subviews.count == 0) { + return; + } + for (UIView *subview in [self subviews]) { + BOOL stop = NO; + block(subview, &stop); + if (stop) { + return; + } + [subview recursiveEnumerateSubviewsUsingBlock:block]; + } +} @end