Permalink
Browse files

Added support for editing mode

  • Loading branch information...
1 parent 4a48d58 commit 94ee7eaaa70dd10e1ad2dfa50eb2966c4d4a1a11 @gmoledina committed Nov 13, 2011
@@ -19,6 +19,7 @@
16924B0C144156FE00E6E556 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 16924B0B144156FE00E6E556 /* UIKit.framework */; };
16924B0E144156FE00E6E556 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 16924B0D144156FE00E6E556 /* Foundation.framework */; };
16924B10144156FE00E6E556 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 16924B0F144156FE00E6E556 /* CoreGraphics.framework */; };
+ 16955523146FA81800DECCA6 /* close_x.png in Resources */ = {isa = PBXBuildFile; fileRef = 16955522146FA81800DECCA6 /* close_x.png */; };
169AE3781460E1B300C0CBCD /* OptionsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 169AE3771460E1B300C0CBCD /* OptionsViewController.m */; };
16A0D030145342F8004D7BBC /* GMGridViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 16A0D02F145342F8004D7BBC /* GMGridViewCell.m */; };
16DF1A6E145E3456006AA43C /* GMGridViewLayoutStrategies.m in Sources */ = {isa = PBXBuildFile; fileRef = 16DF1A6D145E3456006AA43C /* GMGridViewLayoutStrategies.m */; };
@@ -46,6 +47,7 @@
16924B0B144156FE00E6E556 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
16924B0D144156FE00E6E556 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
16924B0F144156FE00E6E556 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
+ 16955522146FA81800DECCA6 /* close_x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = close_x.png; sourceTree = "<group>"; };
169AE3761460E1B300C0CBCD /* OptionsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OptionsViewController.h; path = GMGridView/OptionsViewController.h; sourceTree = SOURCE_ROOT; };
169AE3771460E1B300C0CBCD /* OptionsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OptionsViewController.m; path = GMGridView/OptionsViewController.m; sourceTree = SOURCE_ROOT; };
16A0D02E145342F8004D7BBC /* GMGridViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GMGridViewCell.h; path = GMGridView/API/GMGridViewCell.h; sourceTree = SOURCE_ROOT; };
@@ -85,6 +87,7 @@
children = (
16924B11144156FE00E6E556 /* Demo */,
16924B361442CA9400E6E556 /* API */,
+ 16955520146FA80200DECCA6 /* Resources */,
16026C10145462EC00093AFF /* Documentation */,
16924B0A144156FE00E6E556 /* Frameworks */,
16924B08144156FE00E6E556 /* Products */,
@@ -155,6 +158,15 @@
path = DraggableGridView/API;
sourceTree = "<group>";
};
+ 16955520146FA80200DECCA6 /* Resources */ = {
+ isa = PBXGroup;
+ children = (
+ 16955522146FA81800DECCA6 /* close_x.png */,
+ );
+ name = Resources;
+ path = GMGridView/Resources;
+ sourceTree = "<group>";
+ };
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
@@ -208,6 +220,7 @@
files = (
16026C131454631600093AFF /* LICENSE in Resources */,
16026C141454631600093AFF /* README in Resources */,
+ 16955523146FA81800DECCA6 /* close_x.png in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -66,6 +66,9 @@ typedef enum
@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 - not working right now
+// Editing
+@property (nonatomic, getter=isEditing) BOOL editing; // Default is NO
+
// Actions
- (void)reloadData;
- (void)insertObjectAtIndex:(NSInteger)index;
@@ -117,7 +117,7 @@ - (void)cleanupUnseenItems;
- (void)queueReusableCell:(GMGridViewCell *)cell;
- (GMGridViewCell *)dequeueReusableCell;
-
+// Memory warning
- (void)receivedMemoryWarningNotification:(NSNotification *)notification;
@end
@@ -140,6 +140,7 @@ @implementation GMGridView
@synthesize centerGrid = _centerGrid;
@synthesize minEdgeInsets = _minEdgeInsets;
@synthesize showFullSizeViewWithAlphaWhenTransforming;
+@synthesize editing = _editing;
@synthesize itemsSubviewsCacheIsValid = _itemsSubviewsCacheIsValid;
@synthesize itemSubviewsCache;
@@ -209,6 +210,7 @@ - (id)initWithFrame:(CGRect)frame
self.layoutStrategy = [GMGridViewLayoutStrategyFactory strategyFromType:GMGridViewLayoutVertical];
self.mainSuperView = self;
+ self.editing = NO;
self.itemSpacing = 10;
self.style = GMGridViewStyleSwap;
self.minimumPressDuration = 0.2;
@@ -302,6 +304,20 @@ - (CFTimeInterval)minimumPressDuration
return _sortingLongPressGesture.minimumPressDuration;
}
+- (void)setEditing:(BOOL)editing
+{
+ if (![self isInTransformingState]
+ && ((self.isEditing && !editing) || (!self.isEditing && editing)))
+ {
+ for (GMGridViewCell *cell in [self itemSubviews])
+ {
+ [cell setEditing:editing];
+ }
+
+ _editing = editing;
+ }
+}
+
//////////////////////////////////////////////////////////////
#pragma mark UIScrollView delegate
//////////////////////////////////////////////////////////////
@@ -327,11 +343,11 @@ - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
if (gestureRecognizer == _tapGesture)
{
CGPoint locationTouch = [_tapGesture locationInView:_scrollView];
- valid = [self.layoutStrategy itemPositionFromLocation:locationTouch] != GMGV_INVALID_POSITION;
+ valid = !self.isEditing && [self.layoutStrategy itemPositionFromLocation:locationTouch] != GMGV_INVALID_POSITION;
}
else if (gestureRecognizer == _sortingLongPressGesture)
{
- valid = (self.sortingDelegate != nil);
+ valid = !self.isEditing && (self.sortingDelegate != nil);
}
else if (gestureRecognizer == _sortingPanGesture)
{
@@ -347,7 +363,7 @@ - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
NSInteger positionTouch1 = [self.layoutStrategy itemPositionFromLocation:locationTouch1];
NSInteger positionTouch2 = [self.layoutStrategy itemPositionFromLocation:locationTouch2];
- valid = [self isInTransformingState] || ((positionTouch1 == positionTouch2) && (positionTouch1 != GMGV_INVALID_POSITION));
+ valid = !self.isEditing && ([self isInTransformingState] || ((positionTouch1 == positionTouch2) && (positionTouch1 != GMGV_INVALID_POSITION)));
}
else
{
@@ -966,6 +982,17 @@ - (GMGridViewCell *)createItemSubViewForPosition:(NSInteger)position
if (!cell)
{
cell = [[GMGridViewCell alloc] initContentView:contentView];
+ cell.deleteButtonIcon = [UIImage imageNamed:@"close_x.png"];
+ cell.deleteButtonOffset = CGPointMake(-15, -15);
+ cell.deleteBlock = ^(GMGridViewCell *cell)
+ {
+ NSInteger index = [self positionForItemSubview:cell];
+ if (index != GMGV_INVALID_POSITION)
+ {
+ [self removeObjectAtIndex:index];
+ //todo: tell the delegate !!!!
+ }
+ };
}
else
{
@@ -976,6 +1003,7 @@ - (GMGridViewCell *)createItemSubViewForPosition:(NSInteger)position
cell.frame = CGRectMake(origin.x, origin.y, _itemSize.width, _itemSize.height);
cell.tag = position + kTagOffset;
+ cell.editing = self.editing;
return cell;
}
@@ -1159,9 +1187,9 @@ - (void)cleanupUnseenItems
[self setSubviewsCacheAsInvalid];
}
- if (rangeOfPositions.location + rangeOfPositions.length < self.lastPositionLoaded)
+ if (NSMaxRange(rangeOfPositions) < self.lastPositionLoaded)
{
- for (int i = rangeOfPositions.location + rangeOfPositions.length; i <= self.lastPositionLoaded; i++)
+ for (int i = NSMaxRange(rangeOfPositions); i <= self.lastPositionLoaded; i++)
{
cell = [self itemSubViewForPosition:i];
if(cell)
@@ -1172,7 +1200,7 @@ - (void)cleanupUnseenItems
}
}
- self.lastPositionLoaded = rangeOfPositions.location + rangeOfPositions.length;
+ self.lastPositionLoaded = NSMaxRange(rangeOfPositions);
[self setSubviewsCacheAsInvalid];
}
}
@@ -1182,6 +1210,7 @@ - (void)queueReusableCell:(GMGridViewCell *)cell
if (cell)
{
[cell prepareForReuse];
+ cell.alpha = 1;
[_reusableCells addObject:cell];
}
}
@@ -1348,17 +1377,22 @@ - (void)removeObjectAtIndex:(NSInteger)index
delay:0
options:kDefaultAnimationOptions
animations:^{
- cell.contentView.alpha = 0;
+ cell.contentView.alpha = 0.3;
+ cell.alpha = 0;
[_scrollView scrollRectToVisible:CGRectMake(origin.x, origin.y, _itemSize.width, _itemSize.height) animated:NO];
}
completion:^(BOOL finished){
[self queueReusableCell:cell];
[cell removeFromSuperview];
+
+ self.firstPositionLoaded = self.lastPositionLoaded = GMGV_INVALID_POSITION;
+ [self loadRequiredItems];
+
+ [self setNeedsLayout];
}
];
[self setSubviewsCacheAsInvalid];
- [self setNeedsLayout];
}
- (void)swapObjectAtIndex:(NSInteger)index1 withObjectAtIndex:(NSInteger)index2
@@ -28,6 +28,11 @@
#import <UIKit/UIKit.h>
+@class GMGridViewCell;
+typedef void (^GMGridViewCellDeleteBlock)(GMGridViewCell*);
+
+
+
@interface GMGridViewCell : UIView
@property (nonatomic, strong) UIView *contentView;
@@ -37,6 +42,10 @@
@property (nonatomic, readonly, getter=isInShakingMode) BOOL inShakingMode;
@property (nonatomic, readonly, getter=isInFullSizeMode) BOOL inFullSizeMode;
+@property (nonatomic, getter=isEditing) BOOL editing;
+@property (nonatomic, copy) GMGridViewCellDeleteBlock deleteBlock;
+@property (nonatomic, strong) UIImage *deleteButtonIcon;
+@property (nonatomic) CGPoint deleteButtonOffset;
- (id)initContentView:(UIView *)contentView;
- (void)prepareForReuse;
@@ -40,6 +40,9 @@ @interface GMGridViewCell ()
}
@property (nonatomic, assign) UIViewAutoresizing defaultFullsizeViewResizingMask;
+@property (nonatomic, weak) UIButton *deleteButton;
+
+- (void)actionDelete;
@end
@@ -53,11 +56,16 @@ @interface GMGridViewCell ()
@implementation GMGridViewCell
@synthesize contentView = _contentView;
+@synthesize editing = _editing;
@synthesize inShakingMode = _inShakingMode;
@synthesize fullSize = _fullSize;
@synthesize fullSizeView = _fullSizeView;
@synthesize inFullSizeMode = _inFullSizeMode;
-@synthesize defaultFullsizeViewResizingMask;
+@synthesize defaultFullsizeViewResizingMask = _defaultFullsizeViewResizingMask;
+@synthesize deleteButton = _deleteButton;
+@synthesize deleteBlock = _deleteBlock;
+@synthesize deleteButtonIcon = _deleteButtonIcon;
+@synthesize deleteButtonOffset;
//////////////////////////////////////////////////////////////
#pragma mark Constructors
@@ -78,6 +86,17 @@ - (id)initContentView:(UIView *)contentView
{
self.contentView = contentView;
self.autoresizesSubviews = YES;
+ self.editing = NO;
+
+ 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;
+ [self addSubview:deleteButton];
+ [deleteButton addTarget:self action:@selector(actionDelete) forControlEvents:UIControlEventTouchUpInside];
}
return self;
@@ -109,11 +128,13 @@ - (void)layoutSubviews
- (void)setContentView:(UIView *)contentView
{
[self shake:NO];
- [_contentView removeFromSuperview];
+ [self.contentView removeFromSuperview];
_contentView = contentView;
- _contentView.frame = self.bounds;
- _contentView.autoresizingMask = UIViewAutoresizingNone;
- [self addSubview:_contentView];
+ self.contentView.frame = self.bounds;
+ self.contentView.autoresizingMask = UIViewAutoresizingNone;
+ [self addSubview:self.contentView];
+
+ [self bringSubviewToFront:self.deleteButton];
}
- (void)setFullSizeView:(UIView *)fullSizeView
@@ -136,6 +157,8 @@ - (void)setFullSizeView:(UIView *)fullSizeView
[_fullSizeView removeFromSuperview];
_fullSizeView = fullSizeView;
[self addSubview:_fullSizeView];
+
+ [self bringSubviewToFront:self.deleteButton];
}
- (void)setFullSize:(CGSize)fullSize
@@ -145,6 +168,76 @@ - (void)setFullSize:(CGSize)fullSize
[self setNeedsLayout];
}
+- (void)setEditing:(BOOL)editing
+{
+ _editing = editing;
+
+ [UIView animateWithDuration:0.2
+ delay:0
+ options:UIViewAnimationOptionAllowUserInteraction | UIViewAnimationCurveEaseOut
+ animations:^{
+ self.deleteButton.alpha = editing ? 1 : 0;
+ }
+ completion:nil];
+}
+
+- (void)setDeleteButtonOffset:(CGPoint)offset
+{
+ self.deleteButton.frame = CGRectMake(offset.x,
+ offset.y,
+ self.deleteButton.frame.size.width,
+ self.deleteButton.frame.size.height);
+}
+
+- (CGPoint)deleteButtonOffset
+{
+ return self.deleteButton.frame.origin;
+}
+
+- (void)setDeleteButtonIcon:(UIImage *)deleteButtonIcon
+{
+ [self.deleteButton setImage:deleteButtonIcon forState:UIControlStateNormal];
+
+ if (deleteButtonIcon)
+ {
+ self.deleteButton.frame = CGRectMake(self.deleteButton.frame.origin.x,
+ self.deleteButton.frame.origin.y,
+ deleteButtonIcon.size.width,
+ deleteButtonIcon.size.height);
+
+ [self.deleteButton setTitle:nil forState:UIControlStateNormal];
+ [self.deleteButton setBackgroundColor:[UIColor clearColor]];
+ }
+ else
+ {
+ self.deleteButton.frame = CGRectMake(self.deleteButton.frame.origin.x,
+ self.deleteButton.frame.origin.y,
+ 35,
+ 35);
+
+ [self.deleteButton setTitle:@"X" forState:UIControlStateNormal];
+ [self.deleteButton setBackgroundColor:[UIColor lightGrayColor]];
+ }
+
+
+}
+
+- (UIImage *)deleteButtonIcon
+{
+ return [self.deleteButton currentImage];
+}
+
+//////////////////////////////////////////////////////////////
+#pragma mark Private methods
+//////////////////////////////////////////////////////////////
+
+- (void)actionDelete
+{
+ if (self.deleteBlock)
+ {
+ self.deleteBlock(self);
+ }
+}
//////////////////////////////////////////////////////////////
#pragma mark Public methods
@@ -155,6 +248,7 @@ - (void)prepareForReuse
self.contentView = nil;
self.fullSize = CGSizeZero;
self.fullSizeView = nil;
+ self.editing = NO;
}
- (void)shake:(BOOL)on
Oops, something went wrong.

0 comments on commit 94ee7ea

Please sign in to comment.