forked from ashfurrow/UIView-ShinkTo
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathUITableViewCell+ShrinkTo.m
93 lines (76 loc) · 4.45 KB
/
UITableViewCell+ShrinkTo.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
//Copyright (C) 2011 by Ash Furrow
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
#import "UITableViewCell+ShrinkTo.h"
#import <QuartzCore/QuartzCore.h>
@implementation UITableViewCell (ShrinkTo)
-(void)shrinkToCenterOfView:(UIView *)targetView fromTableView:(UITableView *)theTableView withRemoveFromDataSourceBlock:(void (^)())block
{
[self shrinkToPoint:[self convertPoint:targetView.center fromView:targetView] inView:targetView fromTableView:theTableView withRemoveFromDataSourceBlock:block];
}
-(void)shrinkToPoint:(CGPoint)thePoint inView:(UIView *)targetView fromTableView:(UITableView *)theTableView withRemoveFromDataSourceBlock:(void (^)())block
{
NSIndexPath *indexPath = [theTableView indexPathForCell:self];
//This block should remove the item represented by the cell from the table view's datasource object. Tnis is important, since
//we're calling deleteRowsAtIndexPaths:withRowAnimations later and we'll get an NSInternalConsistencyException if the
//table view differs from its datasource
block();
//we're removing ourselves from our superview before we add ourselves somehwere else - we don't want to get accidentally dealloc'd!
[[self retain] autorelease];
UIView *superview = theTableView;
while (![self isDescendantOfView:superview])
{
superview = [superview superview];
if (superview == nil)
{
NSLog(@"We couldn't find a common ancester view to re-add the cell to.");
return;
}
}
//we're essetially swapping the cell from the table view to a common view ancestor so that we don't get clipped
[theTableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];
[theTableView.superview addSubview:self];
//These animations scale the cell down, reduce it's opacity, and move it along a bezier curve
CABasicAnimation *scaleAnim = [CABasicAnimation animationWithKeyPath:@"transform"];
scaleAnim.fromValue = [NSValue valueWithCATransform3D:CATransform3DIdentity];
scaleAnim.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(0.1, 0.1, 1.0)];
scaleAnim.removedOnCompletion = NO;
CABasicAnimation *opacityAnim = [CABasicAnimation animationWithKeyPath:@"alpha"];
opacityAnim.fromValue = [NSNumber numberWithFloat:1.0];
opacityAnim.toValue = [NSNumber numberWithFloat:0.05];
opacityAnim.removedOnCompletion = NO;
UIBezierPath *movePath = [UIBezierPath bezierPath];
CGPoint ctlPoint1 = CGPointMake(self.center.x, (self.center.y + ((thePoint.y - self.center.y)/2)));
CGPoint ctlPoint2 = CGPointMake((self.center.x + ((thePoint.x - self.center.x) /2)), self.center.y);
[movePath moveToPoint:self.center];
[movePath addCurveToPoint:thePoint controlPoint1:ctlPoint1 controlPoint2:ctlPoint2];
CAKeyframeAnimation *moveAnim = [CAKeyframeAnimation animationWithKeyPath:@"position"];
moveAnim.path = movePath.CGPath;
moveAnim.removedOnCompletion = NO;
CAAnimationGroup *animGroup = [CAAnimationGroup animation];
animGroup.animations = [NSArray arrayWithObjects:moveAnim, scaleAnim, opacityAnim, nil];
animGroup.delegate = self;
[self.layer addAnimation:animGroup forKey:nil];
}
//after we're done animating, we need to remove ourselves from the view so we don't "hang around" on the screen
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
if (!flag) return;
if (self.superview != nil) [self removeFromSuperview];
}
@end