2012-06-19 54 views
5

我想动画的圆角矩形的宽度,问题是当从更大的宽度到更薄的宽度,动画做“像差缓解跳跃”。(iOS)如何用shapeLayer动画圆角矩形?

下面的代码:

shapeLayer = [CAShapeLayer layer]; 
shapeRect = CGRectMake(0.0f, 0.0f, 150.0f, 200.0f); 
[shapeLayer setBounds:shapeRect]; 
[shapeLayer setPosition:CGPointMake(iniPosX, 80.0f)]; 
[shapeLayer setFillColor:[[UIColor blackColor] CGColor]]; 
[shapeLayer setStrokeColor:[[UIColor clearColor] CGColor]]; 
[shapeLayer setLineWidth:1.0f]; 
[shapeLayer setLineJoin:kCALineJoinRound]; 
[shapeLayer setOpacity:0.2]; 
path = [UIBezierPath bezierPathWithRoundedRect:shapeRect cornerRadius:15.0]; 
[shapeLayer setPath:path.CGPath]; 
[self.layer addSublayer:shapeLayer]; 

当我开始动画:

- (void)adjustSelectorToPosAndSize:(float)posX andWidth:(float)width 
{ 
    shapeRect = CGRectMake(0.0f, 0.0f, width, 200.0f); 
    [shapeLayer setBounds:shapeRect]; 
    [shapeLayer setPosition:CGPointMake(posX, 80.0f)]; 
    path = [UIBezierPath bezierPathWithRoundedRect:shapeRect cornerRadius:15.0]; 
    [shapeLayer setPath:path.CGPath]; 
} 

我在做什么错?

+0

感谢Alexis的纠正。 – murb83

回答

3

用CAShapeLayer做这件事对我来说似乎过于复杂,如果你只是将它用于圆角矩形。为什么不简单地使用一个设置为the cornerRadius properly的CALayer?

使用cornerRadius设置动画框架可以正常工作。

一些属性改变名称和类似fillColor成为backgroundColorstrokeColor

myLayer = [CALayer layer]; 
shapeRect = CGRectMake(0.0f, 0.0f, 150.0f, 200.0f); 
[myLayer setBounds:shapeRect]; 
[myLayer setPosition:CGPointMake(iniPosX, 80.0f)]; 
[myLayer setBackgroundColor:[[UIColor blackColor] CGColor]]; 
[myLayer setBorderColor:[[UIColor clearColor] CGColor]]; 
[myLayer setBorderWidth:1.0f]; 
[myLayer setOpacity:0.2]; 
[myLayer setCornerRadius:15.0]; 
[self.layer addSublayer:myLayer]; 

动画是通过简单地链接的框架(而不是路径)

- (void)adjustSelectorToPosAndSize:(float)posX andWidth:(float)width 
{ 
    shapeRect = CGRectMake(0.0f, 0.0f, width, 200.0f); 
    [myLayer setBounds:shapeRect]; 
    [myLayer setPosition:CGPointMake(posX, 80.0f)]; 
} 

重要做并且lineWidth变成了borderColorborderWidth等。

+0

谢谢!但不做动画,是瞬间的。 – murb83

+0

我刚试过。它使用默认的0.3持续时间动画进行动画处理。你是否在做其他任何事情? –

+0

如果你想自定义动画,你需要明确地做到 –

3

虽然CAShapeLayer的路径属性是动画,它没有这样做隐象界和位置,你必须做出一个明确的动画:

CABasicAnimation* anim = [CABasicAnimation animationWithKeyPath: @"path"]; 
anim.fromValue = (id) fromPath.CGPath; 
anim.toValue = (id) toPath.CGPath; 
anim.duration = 1.0; 
[layer addAnimation: anim forKey: @“resize”]; 

因为你很可能要全部三个动画发生一起,你可以让他们都明确而组合在一起:

CABasicAnimation* anim1 = [CABasicAnimation animationWithKeyPath: @"position"]; 
anim1.fromValue = [NSValue valueWithCGPoint: fromPosition]; 
anim1.toValue = [NSValue valueWithCGPoint: toPosition]; 
anim1.duration = 1.0; 

CABasicAnimation* anim2 = [CABasicAnimation animationWithKeyPath: @"bounds"]; 
anim2.fromValue = [NSValue valueWithCGRect: fromBounds]; 
anim2.toValue = [NSValue valueWithCGRect: toBounds]; 
anim2.duration = 1.0; 

CABasicAnimation* anim3 = [CABasicAnimation animationWithKeyPath: @"path"]; 
anim3.fromValue = (id) fromPath.CGPath; 
anim3.toValue = (id) toPath.CGPath; 
anim3.duration = 1.0; 

CAAnimationGroup* animG = [CAAnimationGroup animation]; 
animG.animations = [NSArray arrayWithObjects: anim1, anim2, anim3, nil]; 
animG.duration = 1.0; 
[layer addAnimation: animG forKey:@"resize"]; 

如果你的形状没有内容或孩子,那么你可能能够使用的CALayer代替:

CALayer* rectLayer = [CALayer layer]; 
rectLayer.masksToBounds = YES; 
rectLayer.bounds = startBounds; 
rectLayer.backgroundColor = [[UIColor blackColor] CGColor]; 
rectLayer.cornerRadius = 15.0; 
[self.layer addSublayer: rectLayer]; 

// Then later implicitly animate the bounds: 
rectLayer.bounds = newBounds; 
+0

谢谢!我正在测试你的代码,当你完成测试时我告诉你。 – murb83

+0

我很抱歉,但效果不好,我认为我做错了什么,但图层不会移动到我想要的位置,我认为参考点是不同的,当我做动画。对不起,我的英语不好。您使用动画的方式真的是我的兴趣所在,您向我展示了一种组合动画中的新方式。 ^^ – murb83