CAShapeLayer和动画位置问题

时间:2013-04-06 22:39:57

标签: iphone animation calayer

我正在制作一款在屏幕上画圆圈的iPhone应用程序。我使用一个计时器(每5秒钟),这样我就可以“成长”圆圈,然后等待5秒再重新成长。现在我在设置圆圈大小增加动画时遇到麻烦(我使用路径和CAShapeLayer层)。动画的大小(从和到)都很好,就在它开始时,圆圈移动到左上角并从那里开始增长。任何帮助或建议都会很棒。感谢

实现它的类是UIControl,它被添加到UIView。

//Called in init method
(void) initalPop {
  //Circle
  self.bubble = [CAShapeLayer layer];
  self.bubble.bounds = self.bounds;
  self.bubble.position = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds));
  self.bubble.fillColor = [
    [UIColor greenColor] CGColor
  ];
  self.bubble.strokeColor = [
    [UIColor greenColor] CGColor
  ];
  self.bubble.lineWidth = 4.0;
  CGMutablePathRef path = CGPathCreateMutable();
  CGPathAddEllipseInRect(path, nil, self.bounds);
  self.bubble.path = path;
  [self.layer addSublayer: self.bubble];
}
//Called when timer goes off
- (void) StageGrow {
  CGFloat growSize = 50.0;
  //Change the size of us and center the circle (but dont want to animate this
  [CATransaction begin];
  [CATransaction setValue: (id) kCFBooleanTrue forKey: kCATransactionDisableActions];
  self.bounds = CGRectMake(0, 0, self.bounds.size.width + growSize, self.bounds.size.height + growSize);
  self.bubble.position = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds));
  [CATransaction commit];
  [self ActualGrowCircle];
} - (void) ActualGrowCircle {
  CGMutablePathRef oldPath = CGPathCreateMutable();
  CGPathAddEllipseInRect(oldPath, nil, self.bubble.bounds);
  CGMutablePathRef path = CGPathCreateMutable();
  CGPathAddEllipseInRect(path, nil, self.bounds);
  CABasicAnimation * animation = [CABasicAnimation animationWithKeyPath: @"path"];
  animation.duration = 2.0;
  animation.timingFunction = [CAMediaTimingFunction functionWithName: kCAMediaTimingFunctionEaseInEaseOut];
  animation.repeatCount = 1;
  animation.delegate = self;
  animation.autoreverses = NO;
  animation.fromValue = (__bridge id) oldPath;
  animation.toValue = (__bridge id) path;
  self.bubble.bounds = self.bounds;
  self.bubble.path = path;
  [self.bubble addAnimation: animation forKey: @"animatePath"];
}

2 个答案:

答案 0 :(得分:0)

假设你的气泡从大小(100,100)增加到大小(150,150)。

您在矩形(0,0,100,100)中将oldPath创建为椭圆。

您可以在矩形(0,0,150,150)中将path创建为椭圆。

您可以将气泡图层的边界设置为(0,0,150,150),并且不会对此更改进行动画处理。

这意味着oldPath将显示为与气泡图层的顶部和左侧边缘对齐。

解决此问题的一种方法是在一个以气泡的新边界为中心的矩形中创建oldPath

CGRect oldBubbleRect = CGRectInset(self.bounds, growSize / 2, growSize / 2);
CGPathRef oldPath = CGPathCreateWithEllipseInRect(oldBubbleRect, NULL);

顺便说一下,你正在泄漏你正在创建的路径。完成后,您需要在它们上面调用CGPathRelease

答案 1 :(得分:0)

解决了这个问题。从长远来看,我将动画组合在一起,一切都变得很好(见下面的代码)。谢谢你的帮助Rob。

-(void)ActualGrowCircle {
    CGMutablePathRef newPath = CGPathCreateMutable();
    CGPathAddEllipseInRect(newPath, nil, self.bounds);

    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"path"];
    animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    animation.repeatCount = 1;
    animation.autoreverses = NO;
    animation.fromValue = (__bridge id)self.bubble.path;
    animation.toValue = (__bridge id)newPath;

    CABasicAnimation *animation2 = [CABasicAnimation animationWithKeyPath:@"bounds"];
    animation2.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    animation2.repeatCount = 1;
    animation2.autoreverses = NO;
    animation2.fromValue = [NSValue valueWithCGRect:self.bubble.bounds];
    animation2.toValue = [NSValue valueWithCGRect:self.bounds];

    CAAnimationGroup *group = [CAAnimationGroup animation];
    [group setAnimations:[NSArray arrayWithObjects: animation2, animation, nil]];
    group.duration = 0.5;
    group.delegate = self;

    self.bubble.bounds = self.bounds;
    self.bubble.path = newPath;
    [self.bubble addAnimation:group forKey:@"animateGroup"];

    CGPathRelease(newPath);


}