【问题标题】:CAShapeLayer and animation position issueCAShapeLayer 和动画位置问题
【发布时间】:2013-04-06 22:39:57
【问题描述】:

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

【问题讨论】:

    标签: iphone animation calayer


    【解决方案1】:

    假设您正在将气泡从 (100, 100) 增大到 (150, 150)。

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

    您将path 创建为矩形(0、0、150、150)中的椭圆。

    您将气泡层的边界设置为 (0, 0, 150, 150),并且您没有为该更改设置动画。

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

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

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

    顺便说一句,您正在泄漏您正在创建的路径。完成后,您需要致电CGPathRelease

    【讨论】:

    • 谢谢 rob,今晚会试一试,看看进展如何。哦,也非常感谢您的额外帮助;)
    • 虽然这个周末我会更好地研究它,但仍然没有好的抢劫。
    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多