0

我正在制作一个在屏幕上画一个圆圈的 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"];
}
4

2 回答 2

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给他们。

于 2013-04-07T05:30:31.443 回答
0

解决了。从长远来看,我将动画组合在一起,一切都变得很好(见下面的代码)。感谢您的帮助罗布。

-(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);


}
于 2013-05-20T07:30:43.290 回答