diff --git a/MCSwipe Demo/MCSwipe Demo/MCTableViewController.m b/MCSwipe Demo/MCSwipe Demo/MCTableViewController.m index 42f5319..ca6cf82 100644 --- a/MCSwipe Demo/MCSwipe Demo/MCTableViewController.m +++ b/MCSwipe Demo/MCSwipe Demo/MCTableViewController.m @@ -9,7 +9,7 @@ #import "MCSwipeTableViewCell.h" #import "MCTableViewController.h" -static NSUInteger const kMCNumItems = 7; +static NSUInteger const kMCNumItems = 8; @interface MCTableViewController () @@ -131,6 +131,16 @@ - (void)configureCell:(MCSwipeTableViewCell *)cell forRowAtIndexPath:(NSIndexPat } else if (indexPath.row % kMCNumItems == 2) { + [cell.textLabel setText:@"Sticky Mode Cell"]; + [cell.detailTextLabel setText:@"Swipe to open menu"]; + checkView.frame = CGRectMake(0, 0, 80, 70); + checkView.backgroundColor = greenColor; + [cell setSwipeGestureWithView:checkView color:greenColor mode:MCSwipeTableViewCellModeSticky state:MCSwipeTableViewCellState1 completionBlock:^(MCSwipeTableViewCell *cell, MCSwipeTableViewCellState state, MCSwipeTableViewCellMode mode) { + NSLog(@"Did swipe \"Checkmark\" cell"); + }]; + } + + else if (indexPath.row % kMCNumItems == 3) { [cell.textLabel setText:@"Mixed Mode Cell"]; [cell.detailTextLabel setText:@"Swipe to switch or delete"]; cell.shouldAnimateIcons = YES; @@ -146,7 +156,7 @@ - (void)configureCell:(MCSwipeTableViewCell *)cell forRowAtIndexPath:(NSIndexPat }]; } - else if (indexPath.row % kMCNumItems == 3) { + else if (indexPath.row % kMCNumItems == 4) { [cell.textLabel setText:@"Un-animated Icons"]; [cell.detailTextLabel setText:@"Swipe"]; cell.shouldAnimateIcons = NO; @@ -162,7 +172,7 @@ - (void)configureCell:(MCSwipeTableViewCell *)cell forRowAtIndexPath:(NSIndexPat }]; } - else if (indexPath.row % kMCNumItems == 4) { + else if (indexPath.row % kMCNumItems == 5) { [cell.textLabel setText:@"Right swipe only"]; [cell.detailTextLabel setText:@"Swipe"]; @@ -175,7 +185,7 @@ - (void)configureCell:(MCSwipeTableViewCell *)cell forRowAtIndexPath:(NSIndexPat }]; } - else if (indexPath.row % kMCNumItems == 5) { + else if (indexPath.row % kMCNumItems == 6) { [cell.textLabel setText:@"Small triggers"]; [cell.detailTextLabel setText:@"Using 10% and 50%"]; cell.firstTrigger = 0.1; @@ -192,7 +202,7 @@ - (void)configureCell:(MCSwipeTableViewCell *)cell forRowAtIndexPath:(NSIndexPat }]; } - else if (indexPath.row % kMCNumItems == 6) { + else if (indexPath.row % kMCNumItems == 7) { [cell.textLabel setText:@"Exit Mode Cell + Confirmation"]; [cell.detailTextLabel setText:@"Swipe to delete"]; @@ -257,9 +267,15 @@ - (void)deleteCell:(MCSwipeTableViewCell *)cell { - (UIView *)viewWithImageName:(NSString *)imageName { UIImage *image = [UIImage imageNamed:imageName]; - UIImageView *imageView = [[UIImageView alloc] initWithImage:image]; - imageView.contentMode = UIViewContentModeCenter; - return imageView; + UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, image.size.width, 70.0)]; + [button setImage:image forState:UIControlStateNormal]; + [button addTarget:self action:@selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside]; + button.contentMode = UIViewContentModeCenter; + return button; +} + +- (void)buttonPressed:(id)sender { + NSLog(@"Button pressed"); } #pragma mark - UIAlertViewDelegate diff --git a/MCSwipeTableViewCell/MCSwipeTableViewCell.h b/MCSwipeTableViewCell/MCSwipeTableViewCell.h index 6332226..4476b32 100644 --- a/MCSwipeTableViewCell/MCSwipeTableViewCell.h +++ b/MCSwipeTableViewCell/MCSwipeTableViewCell.h @@ -34,11 +34,14 @@ typedef NS_ENUM(NSUInteger, MCSwipeTableViewCellMode) { /** Disabled swipe. */ MCSwipeTableViewCellModeNone = 0, - /** Upon swipe the cell if exited from the view. Useful for destructive actions. */ + /** Upon swipe the cell is exited from the view. Useful for destructive actions. */ MCSwipeTableViewCellModeExit, - /** Upon swipe the cell if automatically swiped back to it's initial position. */ - MCSwipeTableViewCellModeSwitch + /** Upon swipe the cell is automatically swiped back to it's initial position. */ + MCSwipeTableViewCellModeSwitch, + + /** Upon swipe the cell is automatically swiped back to the width of the view for the swipe gesture. */ + MCSwipeTableViewCellModeSticky }; /** diff --git a/MCSwipeTableViewCell/MCSwipeTableViewCell.m b/MCSwipeTableViewCell/MCSwipeTableViewCell.m index af713be..7e4f7a8 100644 --- a/MCSwipeTableViewCell/MCSwipeTableViewCell.m +++ b/MCSwipeTableViewCell/MCSwipeTableViewCell.m @@ -25,6 +25,8 @@ typedef NS_ENUM(NSUInteger, MCSwipeTableViewCellDirection) { MCSwipeTableViewCellDirectionRight }; +#define SNAPSHOT(view) [view respondsToSelector:@selector(snapshotViewAfterScreenUpdates:)] ? [view snapshotViewAfterScreenUpdates:YES] : [[UIImageView alloc] initWithImage:[self imageWithView:view]] + @interface MCSwipeTableViewCell () @property (nonatomic, assign) MCSwipeTableViewCellDirection direction; @@ -32,7 +34,7 @@ @interface MCSwipeTableViewCell () @property (nonatomic, assign) BOOL isExited; @property (nonatomic, strong) UIPanGestureRecognizer *panGestureRecognizer; -@property (nonatomic, strong) UIImageView *contentScreenshotView; +@property (nonatomic, strong) UIView *contentScreenshotView; @property (nonatomic, strong) UIView *colorIndicatorView; @property (nonatomic, strong) UIView *slidingView; @property (nonatomic, strong) UIView *activeView; @@ -158,17 +160,12 @@ - (void)setupSwipingView { // If the content view background is transparent we get the background color. BOOL isContentViewBackgroundClear = !self.contentView.backgroundColor; - if (isContentViewBackgroundClear) { + BOOL hasBackgroundView = (self.selectedBackgroundView && self.isHighlighted) || (self.backgroundView && !self.isHighlighted); + if (isContentViewBackgroundClear && !hasBackgroundView) { BOOL isBackgroundClear = [self.backgroundColor isEqual:[UIColor clearColor]]; self.contentView.backgroundColor = isBackgroundClear ? [UIColor whiteColor] :self.backgroundColor; } - UIImage *contentViewScreenshotImage = [self imageWithView:self]; - - if (isContentViewBackgroundClear) { - self.contentView.backgroundColor = nil; - } - _colorIndicatorView = [[UIView alloc] initWithFrame:self.bounds]; _colorIndicatorView.autoresizingMask = (UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth); _colorIndicatorView.backgroundColor = self.defaultColor ? self.defaultColor : [UIColor clearColor]; @@ -178,7 +175,25 @@ - (void)setupSwipingView { _slidingView.contentMode = UIViewContentModeCenter; [_colorIndicatorView addSubview:_slidingView]; - _contentScreenshotView = [[UIImageView alloc] initWithImage:contentViewScreenshotImage]; + _contentScreenshotView = [[UIView alloc] initWithFrame:self.bounds]; + + if (self.backgroundView || self.selectedBackgroundView) { + if (self.isHighlighted && self.selectedBackgroundView) { + [_contentScreenshotView addSubview:SNAPSHOT(self.selectedBackgroundView)]; + } + else if (!self.isHighlighted && self.backgroundView) { + [_contentScreenshotView addSubview:SNAPSHOT(self.backgroundView)]; + } + } + else { + [_contentScreenshotView addSubview:SNAPSHOT(self)]; + } + [_contentScreenshotView addSubview:SNAPSHOT(self.contentView)]; + + if (isContentViewBackgroundClear) { + self.contentView.backgroundColor = nil; + } + [self addSubview:_contentScreenshotView]; } @@ -311,9 +326,14 @@ - (void)handlePanGestureRecognizer:(UIPanGestureRecognizer *)gesture { [self moveWithDuration:animationDuration andDirection:_direction]; } - else { + else if (cellMode == MCSwipeTableViewCellModeSwitch || cellState == MCSwipeTableViewCellModeNone) { [self swipeToOriginWithCompletion:^{ - [self executeCompletionBlock]; + [self executeCompletionBlockForState:cellState]; + }]; + } + else { + [self swipeToStickyPositionWithCompletion:^{ + [self executeCompletionBlockForState:cellState]; }]; } @@ -597,7 +617,17 @@ - (void)moveWithDuration:(NSTimeInterval)duration andDirection:(MCSwipeTableView }]; } +- (void)swipeToStickyPositionWithCompletion:(void(^)(void))completion { + self.selectionStyle = UITableViewCellSelectionStyleNone; + UIView *currentView = [self viewWithPercentage:self.currentPercentage]; + [self swipeToOriginWithCompletion:completion offset:CGRectGetWidth(currentView.frame)]; +} + - (void)swipeToOriginWithCompletion:(void(^)(void))completion { + [self swipeToOriginWithCompletion:completion offset:0]; +} + +- (void)swipeToOriginWithCompletion:(void(^)(void))completion offset:(CGFloat)offset { CGFloat bounceDistance = kMCBounceAmplitude * _currentPercentage; if ([UIView.class respondsToSelector:@selector(animateWithDuration:delay:usingSpringWithDamping:initialSpringVelocity:options:animations:completion:)]) { @@ -605,19 +635,31 @@ - (void)swipeToOriginWithCompletion:(void(^)(void))completion { [UIView animateWithDuration:_animationDuration delay:0.0 usingSpringWithDamping:_damping initialSpringVelocity:_velocity options:UIViewAnimationOptionCurveEaseInOut animations:^{ CGRect frame = _contentScreenshotView.frame; - frame.origin.x = 0; + if (self.currentPercentage >= 0) { + frame.origin.x = offset; + } + else { + frame.origin.x = -1 * offset; + } _contentScreenshotView.frame = frame; // Clearing the indicator view - _colorIndicatorView.backgroundColor = self.defaultColor; + if (offset == 0) { + _colorIndicatorView.backgroundColor = self.defaultColor; + _slidingView.alpha = 0; + } + else { + _slidingView.alpha = 1; + } - _slidingView.alpha = 0; [self slideViewWithPercentage:0 view:_activeView isDragging:NO]; } completion:^(BOOL finished) { _isExited = NO; - [self uninstallSwipingView]; + if (offset == 0) { + [self uninstallSwipingView]; + } if (completion) { completion(); @@ -677,6 +719,10 @@ - (UIImage *)imageWithView:(UIView *)view { - (void)executeCompletionBlock { MCSwipeTableViewCellState state = [self stateWithPercentage:_currentPercentage]; + [self executeCompletionBlockForState:state]; +} + +- (void)executeCompletionBlockForState:(MCSwipeTableViewCellState)state { MCSwipeTableViewCellMode mode = MCSwipeTableViewCellModeNone; MCSwipeCompletionBlock completionBlock;