仅水平动画CAGradientLayer

时间:2014-04-25 00:02:54

标签: ios objective-c calayer caanimation cagradientlayer

我正在尝试为CAGradientLayer(渐变和框架)设置动画,当我将框架设置为0时,它会缩小到视图的左上角,我希望它只是动画显示水平。现在,它在水平和垂直方向都是动画到0。

以下是动画目前的样子:

Animating CAGradientLayer

我想要的是它什么时候降到最低,只是水平收缩,并且在整个时间内保持相同的高度。

这是我目前正在使用的代码:

- (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之间。

1 个答案:

答案 0 :(得分: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}]];

如您所见,它与图层的rect完全相同,只是宽度为0.0f。想象一下,这会导致宽度为0.

以上是否有效?是。

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

原因是这会导致框架均匀缩小 - 而不是你想要的。

因此,在创建gradientLayer

时添加此项
gradientLayer.anchorPoint = (CGPoint){0.0f, 0.5f};

再次,我测试了它,并且在这个写作时刻它正在我面前运行。顺便看一下这很有趣。

希望这再次有所帮助。