Created
December 20, 2012 04:49
-
-
Save mayoff/4343026 to your computer and use it in GitHub Desktop.
Animate a CALayer's position starting from its current (possibly mid-animation) position.
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
#import "ViewController.h" | |
#import <QuartzCore/QuartzCore.h> | |
@interface ViewController () | |
@end | |
@implementation ViewController { | |
CALayer *_layer; | |
} | |
static const CGFloat kUpY = 115; | |
static const CGFloat kDownY = 310; | |
- (void)viewDidLoad | |
{ | |
[super viewDidLoad]; | |
_layer = [CALayer layer]; | |
_layer.bounds = CGRectMake(0, 0, 40, 40); | |
_layer.backgroundColor = [UIColor redColor].CGColor; | |
_layer.position = CGPointMake(50, kUpY); | |
[self.view.layer addSublayer:_layer]; | |
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect]; | |
[button setTitle:@"Move" forState:UIControlStateNormal]; | |
[button addTarget:self action:@selector(touchDown:) forControlEvents:UIControlEventTouchDown]; | |
[button addTarget:self action:@selector(touchUp:) forControlEvents:UIControlEventTouchUpInside]; | |
[button addTarget:self action:@selector(touchUp:) forControlEvents:UIControlEventTouchUpOutside]; | |
[button sizeToFit]; | |
button.center = CGPointMake(100, 380); | |
button.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleRightMargin; | |
[self.view addSubview:button]; | |
} | |
- (IBAction)touchDown:(id)sender { | |
[self animateLayer:_layer toY:kDownY withBaseY:kUpY]; | |
} | |
- (IBAction)touchUp:(id)sender { | |
[self animateLayer:_layer toY:kUpY withBaseY:kDownY]; | |
} | |
#if 1 | |
- (void)animateLayer:(CALayer *)layer toY:(CGFloat)y withBaseY:(CGFloat)baseY { | |
CGPoint fromValue = [layer.presentationLayer position]; | |
CGPoint toValue = CGPointMake(fromValue.x, y); | |
layer.position = toValue; | |
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"]; | |
animation.fromValue = [NSValue valueWithCGPoint:fromValue]; | |
animation.toValue = [NSValue valueWithCGPoint:toValue]; | |
animation.duration = 2.0 * (toValue.y - fromValue.y) / (y - baseY); | |
[layer addAnimation:animation forKey:animation.keyPath]; | |
} | |
#else | |
- (void)animateLayer:(CALayer *)layer toY:(CGFloat)y withBaseY:(CGFloat)baseY { | |
CGPoint fromValue = [layer.presentationLayer position]; | |
CGPoint toValue = CGPointMake(fromValue.x, y); | |
layer.position = toValue; | |
UIBezierPath *path = [UIBezierPath bezierPath]; | |
[path moveToPoint:fromValue]; | |
[path addLineToPoint:toValue]; | |
CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position"]; | |
animation.path = path.CGPath; | |
animation.duration = 2.0 * (toValue.y - fromValue.y) / (y - baseY); | |
CAAnimationGroup *group = [CAAnimationGroup animation]; | |
group.duration = animation.duration; | |
group.animations = @[animation]; | |
[layer addAnimation:group forKey:animation.keyPath]; | |
} | |
#endif | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment