Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Fixed insert cell fade animation #86

Merged
merged 3 commits into from

2 participants

Ortwin Gentz, FutureTap Peter Steinberger
Ortwin Gentz, FutureTap

fade-in the cell after the cell move animation made room for it

Peter Steinberger

Kudos Ortwin, great work, I'm sure a lot of people will love those new features! I'm going ahead and merge this, haven't tested it extensively, but it looks great code-wise and I trust you that it actually works :)

Peter Steinberger steipete merged commit 1d9ad9d into from
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on May 2, 2012
  1. Ortwin Gentz, FutureTap

    GMGridView: Fixed insert cell fade animation

    futuretap authored
    fade-in the cell after the cell move animation made room for it
Commits on May 3, 2012
  1. Ortwin Gentz, FutureTap

    Added options enableEditOnLongPress, disableEditOnEmptySpaceTap; adde…

    futuretap authored
    …d -changedEdit: callback; added cell highlighting
  2. Ortwin Gentz, FutureTap
This page is out of date. Refresh to see the latest.
1  Example/Demo1ViewController.m
View
@@ -263,6 +263,7 @@ - (GMGridViewCell *)GMGridView:(GMGridView *)gridView cellForItemAtIndex:(NSInte
label.textAlignment = UITextAlignmentCenter;
label.backgroundColor = [UIColor clearColor];
label.textColor = [UIColor blackColor];
+ label.highlightedTextColor = [UIColor whiteColor];
label.font = [UIFont boldSystemFontOfSize:20];
[cell.contentView addSubview:label];
66 Example/OptionsViewController.m
View
@@ -15,6 +15,7 @@
OptionSectionGeneral = 0,
OptionSectionLayout,
OptionSectionSorting,
+ OptionSectionGestures,
OptionSectionDebug,
OptionSectionsCount
@@ -44,6 +45,14 @@
OptionSortingCount
} OptionsTypeSorting;
+// Options Gestures
+typedef enum {
+ OptionTypeGesturesEditOnTap = 0,
+ OptionTypeGesturesDisableEditOnEmptySpaceTap,
+
+ OptionTypeGesturesCount
+} OptionsTypeGestures;
+
// Options debug
typedef enum {
OptionTypeDebugGridBackground = 0,
@@ -62,6 +71,8 @@ - (void)sortStyleSegmentedControlChanged:(UISegmentedControl *)control;
- (void)layoutCenterSwitchChanged:(UISwitch *)control;
- (void)layoutSpacingSliderChanged:(UISlider *)control;
- (void)layoutInsetsSliderChanged:(UISlider *)control;
+- (void)editOnTapSwitchChanged:(UISwitch *)control;
+- (void)disableEditOnEmptySpaceTapSwitchChanged:(UISwitch *)control;
- (void)debugGridBackgroundSwitchChanged:(UISwitch *)control;
- (void)debugReloadButtonPressed:(UIButton *)control;
@@ -167,6 +178,9 @@ - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInte
case OptionSectionSorting:
title = @"Sorting";
break;
+ case OptionSectionGestures:
+ title = @"Gestures";
+ break;
case OptionSectionDebug:
title = @"Debug";
break;
@@ -190,6 +204,9 @@ - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger
case OptionSectionSorting:
count = OptionSortingCount;
break;
+ case OptionSectionGestures:
+ count = OptionTypeGesturesCount;
+ break;
case OptionSectionDebug:
count = OptionDebugCount;
break;
@@ -208,7 +225,14 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
-
+ else
+ {
+ for (UIView* subview in cell.contentView.subviews) {
+ if ([subview isKindOfClass:[UIPickerView class]]) {
+ [subview removeFromSuperview];
+ }
+ }
+ }
if ([indexPath section] == OptionSectionGeneral)
{
@@ -324,6 +348,36 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N
}
}
}
+ else if ([indexPath section] == OptionSectionGestures)
+ {
+ switch ([indexPath row])
+ {
+ case OptionTypeGesturesEditOnTap:
+ {
+ cell.detailTextLabel.text = @"Edit on Long Tap";
+
+ UISwitch *editOnTapSwitch = [[UISwitch alloc] initWithFrame:CGRectMake(0, 0, 100, 30)];
+ [editOnTapSwitch addTarget:self action:@selector(editOnTapSwitchChanged:) forControlEvents:UIControlEventValueChanged];
+ editOnTapSwitch.on = self.gridView.enableEditOnLongPress;
+
+ cell.accessoryView = editOnTapSwitch;
+
+ break;
+ }
+ case OptionTypeGesturesDisableEditOnEmptySpaceTap:
+ {
+ cell.detailTextLabel.text = @"Disable edit on empty tap";
+
+ UISwitch *disableEditOnEmptyTapSwitch = [[UISwitch alloc] initWithFrame:CGRectMake(0, 0, 100, 30)];
+ [disableEditOnEmptyTapSwitch addTarget:self action:@selector(disableEditOnEmptySpaceTapSwitchChanged:) forControlEvents:UIControlEventValueChanged];
+ disableEditOnEmptyTapSwitch.on = self.gridView.enableEditOnLongPress;
+
+ cell.accessoryView = disableEditOnEmptyTapSwitch;
+
+ break;
+ }
+ }
+ }
else if ([indexPath section] == OptionSectionDebug)
{
switch ([indexPath row])
@@ -472,6 +526,16 @@ - (void)layoutInsetsSliderChanged:(UISlider *)control
[self.gridView layoutSubviewsWithAnimation:GMGridViewItemAnimationFade];
}
+- (void)editOnTapSwitchChanged:(UISwitch *)control
+{
+ self.gridView.enableEditOnLongPress = control.on;
+}
+
+- (void)disableEditOnEmptySpaceTapSwitchChanged:(UISwitch *)control;
+{
+ self.gridView.disableEditOnEmptySpaceTap = control.on;
+}
+
- (void)debugGridBackgroundSwitchChanged:(UISwitch *)control
{
self.gridView.backgroundColor = control.on ? [UIColor lightGrayColor] : [UIColor clearColor];
4 GMGridView/GMGridView.h
View
@@ -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
80 GMGridView/GMGridView.m
View
@@ -45,7 +45,7 @@ @interface GMGridView () <UIGestureRecognizerDelegate, UIScrollViewDelegate>
{
// 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,6 +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];
+ }
[self addSubview:cell];
}
1  GMGridView/GMGridViewCell.h
View
@@ -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;
33 GMGridView/GMGridViewCell.m
View
@@ -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
{
2  GMGridView/UIView+GMGridViewAdditions.h
View
@@ -32,5 +32,5 @@
@interface UIView (GMGridViewAdditions)
- (void)shakeStatus:(BOOL)enabled;
-
+- (void)recursiveEnumerateSubviewsUsingBlock:(void (^)(UIView *view, BOOL *stop))block;
@end
13 GMGridView/UIView+GMGridViewAdditions.m
View
@@ -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
6 README.md
View
@@ -64,6 +64,7 @@ New feature requests are welcome. (ping [@gmoledina](http://twitter.com/gmoledin
* Paging!! 2 horizontally paged layout strategies added
* shaking animation on items when in edit mode
* Changing the scrollview delegate is allowed!
+* Cell highlighting support
* Demo app provided, with options panel
**Features - Sorting**:
@@ -73,6 +74,11 @@ New feature requests are welcome. (ping [@gmoledina](http://twitter.com/gmoledin
* Sorted view has a shake animation (can be disabled)
* Only one UIPanGestureRecognizer and one UILongTouchGestureRecognizer used to track ALL views
+**Features - Gestures**:
+
+* Perform a long-press to switch to edit (jiggle) mode
+* Tap between cells to terminate edit mode
+
**Features - Fullsize**:
* Pinch, rotate and drag views using 2 fingers
Something went wrong with that request. Please try again.