Skip to content

Commit

Permalink
- Refactor and features into two different protocols
Browse files Browse the repository at this point in the history
  • Loading branch information
jamztang committed Feb 21, 2012
1 parent 9e5b195 commit 6746ca8
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 49 deletions.
26 changes: 21 additions & 5 deletions JTGestureBasedTableView/JTTableViewGestureRecognizer.h
Expand Up @@ -16,18 +16,25 @@ typedef enum {

extern CGFloat const JTTableViewCommitEditingRowDefaultLength;

@protocol JTTableViewGestureDelegate;
@protocol JTTableViewGestureAddingRowDelegate;
@protocol JTTableViewGestureEditingRowDelegate;


@interface JTTableViewGestureRecognizer : NSObject <UITableViewDelegate>

@property (nonatomic, assign, readonly) UITableView *tableView;

+ (JTTableViewGestureRecognizer *)gestureRecognizerWithTableView:(UITableView *)tableView delegate:(id <JTTableViewGestureDelegate>)delegate;
+ (JTTableViewGestureRecognizer *)gestureRecognizerWithTableView:(UITableView *)tableView delegate:(id)delegate;

@end


@protocol JTTableViewGestureDelegate <NSObject, UITableViewDelegate>
#pragma mark -

// Conform to JTTableViewGestureAddingRowDelegate to enable features
// - drag down to add cell
// - pinch to add cell
@protocol JTTableViewGestureAddingRowDelegate <NSObject>

- (void)gestureRecognizer:(JTTableViewGestureRecognizer *)gestureRecognizer needsAddRowAtIndexPath:(NSIndexPath *)indexPath;
- (void)gestureRecognizer:(JTTableViewGestureRecognizer *)gestureRecognizer needsCommitRowAtIndexPath:(NSIndexPath *)indexPath;
Expand All @@ -38,11 +45,20 @@ extern CGFloat const JTTableViewCommitEditingRowDefaultLength;
- (NSIndexPath *)gestureRecognizer:(JTTableViewGestureRecognizer *)gestureRecognizer willCreateCellAtIndexPath:(NSIndexPath *)indexPath;
- (CGFloat)heightForCommittingRowForGestureRecognizer:(JTTableViewGestureRecognizer *)gestureRecognizer;

@end


// Conform to JTTableViewGestureEditingRowDelegate to enable features
// - swipe to edit cell
@protocol JTTableViewGestureEditingRowDelegate <NSObject>

// Panning (required)
- (BOOL)gestureRecognizer:(JTTableViewGestureRecognizer *)gestureRecognizer canEditRowAtIndexPath:(NSIndexPath *)indexPath;
- (void)gestureRecognizer:(JTTableViewGestureRecognizer *)gestureRecognizer didEnterEditingState:(JTTableViewCellEditingState)state forRowAtIndexPath:(NSIndexPath *)indexPath;
- (void)gestureRecognizer:(JTTableViewGestureRecognizer *)gestureRecognizer commitEditingState:(JTTableViewCellEditingState)state forRowAtIndexPath:(NSIndexPath *)indexPath;
// Panning (optional configuration)

@optional

- (CGFloat)gestureRecognizer:(JTTableViewGestureRecognizer *)gestureRecognizer lengthForCommitEditingRowAtIndexPath:(NSIndexPath *)indexPath;
- (void)gestureRecognizer:(JTTableViewGestureRecognizer *)gestureRecognizer didChangeContentViewTranslation:(CGPoint)translation forRowAtIndexPath:(NSIndexPath *)indexPath;

Expand All @@ -54,6 +70,6 @@ extern CGFloat const JTTableViewCommitEditingRowDefaultLength;

@interface UITableView (JTTableViewGestureDelegate)

- (JTTableViewGestureRecognizer *)enableGestureTableViewWithDelegate:(id <JTTableViewGestureDelegate>)delegate;
- (JTTableViewGestureRecognizer *)enableGestureTableViewWithDelegate:(id)delegate;

@end
44 changes: 34 additions & 10 deletions JTGestureBasedTableView/JTTableViewGestureRecognizer.m
Expand Up @@ -18,8 +18,8 @@
CGFloat const JTTableViewCommitEditingRowDefaultLength = 80;

@interface JTTableViewGestureRecognizer () <UIGestureRecognizerDelegate>
@property (nonatomic, assign) id <JTTableViewGestureDelegate> delegate;
@property (nonatomic, assign) id <UITableViewDelegate> tableViewDelegate;
@property (nonatomic, assign) id <JTTableViewGestureAddingRowDelegate, JTTableViewGestureEditingRowDelegate> delegate;
@property (nonatomic, assign) id <UITableViewDelegate> tableViewDelegate;
@property (nonatomic, assign) UITableView *tableView;
@property (nonatomic, assign) CGFloat addingRowHeight;
@property (nonatomic, retain) NSIndexPath *addingIndexPath;
Expand Down Expand Up @@ -217,6 +217,10 @@ - (void)panGestureRecognizer:(UIPanGestureRecognizer *)recognizer {
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {

if (gestureRecognizer == self.panRecognizer) {
if ( ! [self.delegate conformsToProtocol:@protocol(JTTableViewGestureEditingRowDelegate)]) {
return NO;
}

UIPanGestureRecognizer *pan = (UIPanGestureRecognizer *)gestureRecognizer;

CGPoint point = [pan translationInView:self.tableView];
Expand All @@ -231,12 +235,14 @@ - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
} else if (indexPath == nil) {
return NO;
} else if (indexPath) {
BOOL canEditRow = NO;
if ([self.delegate respondsToSelector:@selector(gestureRecognizer:canEditRowAtIndexPath:)]) {
canEditRow = [self.delegate gestureRecognizer:self canEditRowAtIndexPath:indexPath];
}
BOOL canEditRow = [self.delegate gestureRecognizer:self canEditRowAtIndexPath:indexPath];
return canEditRow;
}
} else if (gestureRecognizer == self.pinchRecognizer) {
if ( ! [self.delegate conformsToProtocol:@protocol(JTTableViewGestureAddingRowDelegate)]) {
NSLog(@"Should not begin pinch");
return NO;
}
}
return YES;
}
Expand All @@ -258,6 +264,13 @@ - (CGFloat)tableView:(UITableView *)aTableView heightForRowAtIndexPath:(NSIndexP
#pragma mark UIScrollViewDelegate

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if ( ! [self.delegate conformsToProtocol:@protocol(JTTableViewGestureAddingRowDelegate)]) {
if ([self.tableViewDelegate respondsToSelector:@selector(scrollViewDidScroll:)]) {
[self.tableViewDelegate scrollViewDidScroll:scrollView];
}
return;
}

// We try to create a new cell when the user tries to drag the content to and offset of negative value
if (scrollView.contentOffset.y < 0) {
// Here we make sure we're not conflicting with the pinch event,
Expand Down Expand Up @@ -289,6 +302,13 @@ - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
}

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
if ( ! [self.delegate conformsToProtocol:@protocol(JTTableViewGestureAddingRowDelegate)]) {
if ([self.tableViewDelegate respondsToSelector:@selector(scrollViewDidEndDragging:willDecelerate:)]) {
[self.tableViewDelegate scrollViewDidEndDragging:scrollView willDecelerate:decelerate];
}
return;
}

if (self.state == JTTableViewGestureRecognizerStateDragging) {
self.state = JTTableViewGestureRecognizerStateNone;
[self commitOrDiscardCell];
Expand All @@ -315,20 +335,21 @@ - (BOOL)respondsToSelector:(SEL)aSelector {

#pragma mark Class method

+ (JTTableViewGestureRecognizer *)gestureRecognizerWithTableView:(UITableView *)tableView delegate:(id<JTTableViewGestureDelegate>)delegate {
+ (JTTableViewGestureRecognizer *)gestureRecognizerWithTableView:(UITableView *)tableView delegate:(id)delegate {
JTTableViewGestureRecognizer *recognizer = [[JTTableViewGestureRecognizer alloc] init];
recognizer.delegate = delegate;
recognizer.delegate = (id)delegate;
recognizer.tableView = tableView;
recognizer.tableViewDelegate = tableView.delegate; // Assign the delegate before chaning the tableView's delegate
tableView.delegate = recognizer;

UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc] initWithTarget:recognizer action:@selector(pinchGestureRecognizer:)];
[tableView addGestureRecognizer:pinch];
pinch.delegate = recognizer;
recognizer.pinchRecognizer = pinch;

UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:recognizer action:@selector(panGestureRecognizer:)];
[tableView addGestureRecognizer:pan];
pan.delegate = recognizer;
pan.delegate = recognizer;
recognizer.panRecognizer = pan;

return recognizer;
Expand All @@ -339,7 +360,10 @@ + (JTTableViewGestureRecognizer *)gestureRecognizerWithTableView:(UITableView *)

@implementation UITableView (JTTableViewGestureDelegate)

- (JTTableViewGestureRecognizer *)enableGestureTableViewWithDelegate:(id <JTTableViewGestureDelegate>)delegate {
- (JTTableViewGestureRecognizer *)enableGestureTableViewWithDelegate:(id)delegate {
if ( ! [delegate conformsToProtocol:@protocol(JTTableViewGestureAddingRowDelegate)] && ! [delegate conformsToProtocol:@protocol(JTTableViewGestureEditingRowDelegate)]) {
[NSException raise:@"delegate should at least conform to one of JTTableViewGestureAddingRowDelegate or JTTableViewGestureEditingRowDelegate" format:nil];
}
JTTableViewGestureRecognizer *recognizer = [JTTableViewGestureRecognizer gestureRecognizerWithTableView:self delegate:delegate];
return recognizer;
}
Expand Down
21 changes: 9 additions & 12 deletions JTGestureBasedTableViewDemo/ViewController.m
Expand Up @@ -11,7 +11,9 @@
#import "JTTableViewGestureRecognizer.h"
#import "UIColor+JTGestureBasedTableViewHelper.h"

@interface ViewController () <JTTableViewGestureDelegate>
// Configure your viewController to conform to JTTableViewGestureEditingRowDelegate
// and/or JTTableViewGestureAddingRowDelegate depends on your needs
@interface ViewController () <JTTableViewGestureEditingRowDelegate, JTTableViewGestureAddingRowDelegate>
@property (nonatomic, strong) NSMutableArray *rows;
@property (nonatomic, strong) JTTableViewGestureRecognizer *tableViewRecognizer;
@end
Expand Down Expand Up @@ -44,9 +46,9 @@ - (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// Setup your tableView.delegate and tableView.datasource first, then enable gesture
// recognition in one line.

// Setup your tableView.delegate and tableView.datasource,
// then enable gesture recognition in one line.
self.tableViewRecognizer = [self.tableView enableGestureTableViewWithDelegate:self];

self.tableView.backgroundColor = [UIColor blackColor];
Expand Down Expand Up @@ -124,11 +126,11 @@ - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPa
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(@"%@", indexPath);
NSLog(@"tableView:didSelectRowAtIndexPath: %@", indexPath);
}

#pragma mark -
#pragma mark JTTableViewGestureRecognizer (Pinch)
#pragma mark JTTableViewGestureAddingRowDelegate

- (void)gestureRecognizer:(JTTableViewGestureRecognizer *)gestureRecognizer needsAddRowAtIndexPath:(NSIndexPath *)indexPath {
[self.rows insertObject:ADDING_CELL atIndex:indexPath.row];
Expand All @@ -145,7 +147,7 @@ - (void)gestureRecognizer:(JTTableViewGestureRecognizer *)gestureRecognizer need
[self.rows removeObjectAtIndex:indexPath.row];
}

#pragma mark JTTableViewGestureRecognizer (Pan)
#pragma mark JTTableViewGestureEditingRowDelegate

- (void)gestureRecognizer:(JTTableViewGestureRecognizer *)gestureRecognizer didEnterEditingState:(JTTableViewCellEditingState)state forRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
Expand Down Expand Up @@ -191,9 +193,4 @@ - (void)gestureRecognizer:(JTTableViewGestureRecognizer *)gestureRecognizer comm
[tableView endUpdates];
}

// Optional delegate method to implement for configuration of cell commitEditing length
- (CGFloat)gestureRecognizer:(JTTableViewGestureRecognizer *)gestureRecognizer lengthForCommitEditingRowAtIndexPath:(NSIndexPath *)indexPath {
return JTTableViewCommitEditingRowDefaultLength;
}

@end
66 changes: 44 additions & 22 deletions README.md
Expand Up @@ -17,9 +17,9 @@ Clear for iPhone app has showed us so much we can do with a buttonless interface
Demo
----

<img src=https://github.com/mystcolor/JTGestureBasedTableViewDemo/raw/master/demo1.png width=320></img>
<img src=https://github.com/mystcolor/JTGestureBasedTableViewDemo/raw/master/demo2.png width=320></img>
<img src=https://github.com/mystcolor/JTGestureBasedTableViewDemo/raw/master/demo3.png width=320></img>
<img src=https://github.com/mystcolor/JTGestureBasedTableViewDemo/raw/master/demo1.png width=280 style="border: 1px solid white;"></img>
<img src=https://github.com/mystcolor/JTGestureBasedTableViewDemo/raw/master/demo2.png width=280 style="border: 1px solid white;"></img>
<img src=https://github.com/mystcolor/JTGestureBasedTableViewDemo/raw/master/demo3.png width=280 style="border: 1px solid white;"></img>


Features
Expand All @@ -44,7 +44,7 @@ Include all header and implementation files in JTGestureBasedTabeView/ into your

#import "JTTableViewGestureRecognizer.h"

@interface ViewController () <JTTableViewGestureDelegate>
@interface ViewController () <JTTableViewGestureAddingRowDelegate, JTTableViewGestureEditingRowDelegate>
@property (nonatomic, strong) NSMutableArray *rows;
@property (nonatomic, strong) JTTableViewGestureRecognizer *tableViewRecognizer;
@end
Expand All @@ -60,31 +60,53 @@ Include all header and implementation files in JTGestureBasedTabeView/ into your
// In our examples, we setup self.rows as datasource
self.rows = ...;
// Setup your tableView.delegate and tableView.datasource first, then enable gesture
// recognition in one line.
// Setup your tableView.delegate and tableView.datasource,
// then enable gesture recognition in one line.
self.tableViewRecognizer = [self.tableView enableGestureTableViewWithDelegate:self];
}


### Implement the JTTableViewGestureDelegate, and also those official UITableViewDatasource @required methods
### Enabling adding cell gestures

// Conform to JTTableViewGestureAddingRowDelegate to enable features
// - drag down to add cell
// - pinch to add cell
@protocol JTTableViewGestureAddingRowDelegate <NSObject>

- (void)gestureRecognizer:(JTTableViewGestureRecognizer *)gestureRecognizer needsAddRowAtIndexPath:(NSIndexPath *)indexPath;
- (void)gestureRecognizer:(JTTableViewGestureRecognizer *)gestureRecognizer needsCommitRowAtIndexPath:(NSIndexPath *)indexPath;
- (void)gestureRecognizer:(JTTableViewGestureRecognizer *)gestureRecognizer needsDiscardRowAtIndexPath:(NSIndexPath *)indexPath;

@optional

- (NSIndexPath *)gestureRecognizer:(JTTableViewGestureRecognizer *)gestureRecognizer willCreateCellAtIndexPath:(NSIndexPath *)indexPath;
- (CGFloat)heightForCommittingRowForGestureRecognizer:(JTTableViewGestureRecognizer *)gestureRecognizer;

@end


### Enabling editing cell gestures

// Conform to JTTableViewGestureEditingRowDelegate to enable features
// - swipe to edit cell
@protocol JTTableViewGestureEditingRowDelegate <NSObject>

// Panning (required)
- (BOOL)gestureRecognizer:(JTTableViewGestureRecognizer *)gestureRecognizer canEditRowAtIndexPath:(NSIndexPath *)indexPath;
- (void)gestureRecognizer:(JTTableViewGestureRecognizer *)gestureRecognizer didEnterEditingState:(JTTableViewCellEditingState)state forRowAtIndexPath:(NSIndexPath *)indexPath;
- (void)gestureRecognizer:(JTTableViewGestureRecognizer *)gestureRecognizer commitEditingState:(JTTableViewCellEditingState)state forRowAtIndexPath:(NSIndexPath *)indexPath;

@optional

- (CGFloat)gestureRecognizer:(JTTableViewGestureRecognizer *)gestureRecognizer lengthForCommitEditingRowAtIndexPath:(NSIndexPath *)indexPath;
- (void)gestureRecognizer:(JTTableViewGestureRecognizer *)gestureRecognizer didChangeContentViewTranslation:(CGPoint)translation forRowAtIndexPath:(NSIndexPath *)indexPath;

@end

#pragma mark JTTableViewGestureRecognizer

- (void)gestureRecognizer:(JTTableViewGestureRecognizer *)gestureRecognizer needsAddRowAtIndexPath:(NSIndexPath *)indexPath {
[self.rows insertObject:ADDING_CELL atIndex:indexPath.row];
}

- (void)gestureRecognizer:(JTTableViewGestureRecognizer *)gestureRecognizer needsCommitRowAtIndexPath:(NSIndexPath *)indexPath {
[self.rows replaceObjectAtIndex:indexPath.row withObject:@"Added!"];
UITableViewCell *cell = (id)[gestureRecognizer.tableView cellForRowAtIndexPath:indexPath];
cell.textLabel.text = @"Just Added!";
}

- (void)gestureRecognizer:(JTTableViewGestureRecognizer *)gestureRecognizer needsDiscardRowAtIndexPath:(NSIndexPath *)indexPath {
[self.rows removeObjectAtIndex:indexPath.row];
}

### You choose what to enable

You can pick what gestures to be enabled by conforming to the appropriate protocols.
Don't forget to look at JTGestureBasedTableViewDemo/ViewController.m for a complete working usage.


Expand Down

0 comments on commit 6746ca8

Please sign in to comment.