Created
April 20, 2014 03:03
-
-
Save samnm/11103881 to your computer and use it in GitHub Desktop.
A super-quick clone of Facebook Paper's springy table view
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// ABSpringDemoViewController.m | |
// Springy | |
// | |
#import "ABSpringDemoViewController.h" | |
@interface ABSpringDemoViewController () <UITableViewDataSource, UITableViewDelegate> { | |
UITableView *_tableView; | |
CADisplayLink *_displayLink; | |
UIPanGestureRecognizer *_panGestureRecognizer_; | |
NSMutableArray *_objects; | |
CGFloat _panOrigin; | |
CGPoint _panPosition; | |
CGPoint _panTranslation; | |
BOOL _isDragging; | |
} | |
@end | |
@implementation ABSpringDemoViewController | |
- (void)loadView { | |
_tableView = [[UITableView alloc] initWithFrame:CGRectZero]; | |
_tableView.delegate = self; | |
_tableView.dataSource = self; | |
self.view = _tableView; | |
_displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(onEnterFrame:)]; | |
[_displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode]; | |
_objects = [NSMutableArray arrayWithArray:@[ | |
@"Red", | |
@"Orange", | |
@"Yellow", | |
@"Green", | |
@"Cyan", | |
@"Blue", | |
@"Violet", | |
@"Purple", | |
@"Magenta", | |
@"Pink", | |
@"White", | |
@"Gray", | |
@"Black", | |
]]; | |
_panGestureRecognizer_ = [[UIPanGestureRecognizer alloc] initWithTarget:self | |
action:@selector(panGestureChanged:)]; | |
[self.view addGestureRecognizer:_panGestureRecognizer_]; | |
} | |
- (void)onEnterFrame:(id)sender { | |
if (!_isDragging) return; | |
NSArray *visibleCells = [_tableView visibleCells]; | |
UIView *touchedCell = [self getCellForPosition:_panPosition]; | |
NSUInteger touchedCellIndex = [visibleCells indexOfObject:touchedCell]; | |
[self dragView:touchedCell withTarget:_panTranslation]; | |
for (NSInteger i = touchedCellIndex + 1; i < visibleCells.count; i++) { | |
UITableViewCell *cell = [visibleCells objectAtIndex:i]; | |
UITableViewCell *target = [visibleCells objectAtIndex:i - 1]; | |
[self dragView:cell withTarget:target.frame.origin]; | |
} | |
for (NSInteger i = touchedCellIndex - 1; i >= 0; i--) { | |
UITableViewCell *cell = [visibleCells objectAtIndex:i]; | |
UITableViewCell *target = [visibleCells objectAtIndex:i + 1]; | |
[self dragView:cell withTarget:target.frame.origin]; | |
} | |
} | |
- (void)dragView:(UIView *)view withTarget:(CGPoint)target { | |
CGFloat dx = (target.x - view.frame.origin.x) * 0.3; | |
view.transform = CGAffineTransformTranslate(view.transform, dx, 0); | |
} | |
- (UITableViewCell *)getCellForPosition:(CGPoint)position { | |
NSArray *visibleCells = [_tableView visibleCells]; | |
for (UITableViewCell *cell in visibleCells) { | |
if (CGRectGetMaxY(cell.frame) > position.y) { | |
return cell; | |
} | |
} | |
return [visibleCells lastObject]; | |
} | |
- (void)panGestureChanged:(UIPanGestureRecognizer *)gestureRecognizer { | |
CGPoint translation = [gestureRecognizer translationInView:self.view]; | |
switch (gestureRecognizer.state) { | |
case UIGestureRecognizerStateBegan: | |
_panOrigin = translation.x; | |
_isDragging = YES; | |
case UIGestureRecognizerStateChanged: | |
_panPosition = [gestureRecognizer locationInView:self.view]; | |
_panTranslation = [gestureRecognizer translationInView:self.view]; | |
break; | |
case UIGestureRecognizerStateEnded: { | |
[UIView animateWithDuration:0.4 animations:^{ | |
for (NSIndexPath *index in [_tableView indexPathsForVisibleRows]) { | |
UITableViewCell *cell = [_tableView cellForRowAtIndexPath:index]; | |
CGRect frame = cell.frame; | |
frame.origin.x = 0; | |
cell.frame = frame; | |
} | |
}]; | |
} | |
default: | |
_isDragging = NO; | |
break; | |
} | |
} | |
#pragma mark - Table View | |
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { | |
return 1; | |
} | |
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { | |
return _objects.count; | |
} | |
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { | |
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"]; | |
if (!cell) { | |
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"]; | |
} | |
NSDate *object = _objects[indexPath.row]; | |
cell.textLabel.text = [object description]; | |
cell.selectionStyle = UITableViewCellSelectionStyleNone; | |
return cell; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment