Skip to content

Instantly share code, notes, and snippets.

@mayoff
Created December 20, 2012 04:49
Show Gist options
  • Save mayoff/4343026 to your computer and use it in GitHub Desktop.
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.
#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