2014-04-25 57 views
2

我想动画一个CAGradientLayer(渐变和框架),当我动画框为0,它收缩到视图的左上角,我希望它只是水平地动画。现在它的动画水平和垂直都是0。水平只动画CAGradientLayer

这里是动画目前的样子:

Animating CAGradientLayer

我要的是当它下降到没什么,只是收缩水平ONLY,并保持相同高度的整个时间。

这里是我目前使用的代码:

- (void)drawRect:(CGRect)rect 
{ 
// Drawing code 
if (!gradientLayer) { 
    gradientLayer = [CAGradientLayer layer]; 
    [gradientLayer setFrame:[self createRectForFrame:rect]]; 
    [gradientLayer setColors:@[(id)fromColor.CGColor, (id)toColor.CGColor]]; 
    [gradientLayer setStartPoint:CGPointMake(fillPct/100, 0.5)]; 
    [gradientLayer setEndPoint:CGPointMake(1.0, 0.5)]; 
    [self.layer addSublayer:gradientLayer]; 
} 
else { 
    [gradientLayer removeAllAnimations]; 

    [CATransaction begin]; 

    [CATransaction setAnimationDuration:ANIMATION_DURATION]; 
    CGRect newFrame = [self createRectForFrame:rect]; 
    CABasicAnimation *frameAnimation = [CABasicAnimation animationWithKeyPath:@"frame"]; 
    [frameAnimation setDuration:ANIMATION_DURATION]; 
    [frameAnimation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]]; 
    [frameAnimation setFromValue:[NSValue valueWithCGRect:gradientLayer.bounds]]; 
    [frameAnimation setToValue:[NSValue valueWithCGRect:newFrame]]; 
    [frameAnimation setFillMode:kCAFillModeForwards]; 
    [frameAnimation setRemovedOnCompletion:NO]; 
    [gradientLayer setFrame:newFrame]; 
    [gradientLayer addAnimation:frameAnimation forKey:@"frame"]; 

    CGPoint startPoint = CGPointMake(MIN(fillPct/100, 0.99), 0.5); 
    CABasicAnimation *startPointAnimation = [CABasicAnimation animationWithKeyPath:@"startPoint"]; 
    [startPointAnimation setDuration:ANIMATION_DURATION]; 
    [startPointAnimation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]]; 
    [startPointAnimation setFromValue:[NSValue valueWithCGPoint:gradientLayer.startPoint]]; 
    [startPointAnimation setToValue:[NSValue valueWithCGPoint:startPoint]]; 
    [startPointAnimation setFillMode:kCAFillModeForwards]; 
    [startPointAnimation setRemovedOnCompletion:NO]; 
    [gradientLayer setStartPoint:startPoint]; 
    [gradientLayer addAnimation:startPointAnimation forKey:@"startPoint"]; 

    [CATransaction setCompletionBlock:^{ 
     [self updateInnerLabelTextColor]; 
    }]; 

    [CATransaction commit]; 
} 
[self bringInnerLabelToFront]; 
} 

- (CGRect)createRectForFrame:(CGRect)frame { 
if (fillPct == 0) 
    return CGRectZero; 
else if (fillPct >= 100) 
    return frame; 
else 
    return CGRectMake(frame.origin.x, frame.origin.y, frame.size.width * (fillPct/100), frame.size.height); 
} 

fillPct是酒吧应填充值,0和100

+0

drawRect不是正确的地方,因为它不使用核心图形,但核心动画 – Felix

回答

2

之间的问题是这一行:

CGPoint startPoint = CGPointMake(MIN(fillPct/100, 0.99), 0.5); 

如果将其更改为:

CGPoint startPoint = CGPointMake(0.0, 0.5); 

它会按照你的意愿工作 - 不会在角落收缩。

或者,如果你想保持当前的代码,更改此值会工作,以及:

CGPoint startPoint = CGPointMake(MIN(fillPct/100, 0.0), 0.5); 

只是测试它;它横向动画。希望这可以帮助。

更新1:

我还真没遇到你在评论中提及的问题;但是,我决定再看一遍。既然你没有提供任何价值的rect以及你反复调用这个的方式,我想出了我自己的,并再次测试它。

我成立了gradientLayer这个值:

[gradientLayer setFrame:(CGRect){{150.0f, 240.0f}, 150.0f, 20.0f}]; 

在第一CABasicAnimation,用于测试目的,我改变了这一点:

[frameAnimation setToValue:[NSValue valueWithCGRect:(CGRect){{150.0f, 240.0f}, 0.0f, 20.0f}]]; 

正如你所看到的,它是完全一样的作为图层的矩形,除了宽度是0.0f。想象一下,这将导致宽度为0.

以上是否工作?是。

上述工作是否符合您的要求?

原因是,这将导致框架收缩均匀 - 不是你想要的。

因此,添加此当你创建gradientLayer

gradientLayer.anchorPoint = (CGPoint){0.0f, 0.5f}; 

同样,我测试了它和它在这个时候写的我面前跑。顺便看一下很有趣。

希望这个,再次,帮助。

+0

我试着改变那条线,但是当fillPct值= 0,它从createRectForFrame函数返回CGRectZero时,它仍然收缩成角落而不是水平地缩小。 – loydbrahn

+0

@loydbrahn请参阅更新。 – Unheilig