绘制矩形、圆形并动画改变大小/颜色

29

我正在使用UIView-drawRect:方法,使用标准的CGContextFillEllipseInRect()代码画一个圆。不过,我希望能够通过动画稍微脉动(放大和缩小)并改变填充颜色的强度。例如,如果圆填充为红色,我希望在脉动的同时使红色略微变亮和变暗。由于我对核心动画没有太多经验,所以有点迷茫,希望能得到帮助。

1个回答

71

如果你不在drawRect:中绘制圆形,这会变得更加简单。 相反,设置您的视图使用一个CAShapeLayer,像这样:

@implementation PulseView

+ (Class)layerClass {
    return [CAShapeLayer class];
}
系统会在视图大小发生变化(包括首次出现)时向您的视图发送 layoutSubviews 消息。 我们重写 layoutSubviews 以设置形状并进行动画处理:
- (void)layoutSubviews {
    [self setLayerProperties];
    [self attachAnimations];
}

以下是我们如何设置图层的路径(决定其形状)和形状的填充颜色:

- (void)setLayerProperties {
    CAShapeLayer *layer = (CAShapeLayer *)self.layer;
    layer.path = [UIBezierPath bezierPathWithOvalInRect:self.bounds].CGPath;
    layer.fillColor = [UIColor colorWithHue:0 saturation:1 brightness:.8 alpha:1].CGColor;
}

我们需要将两个动画附加到图层上 - 一个用于路径,另一个用于填充颜色:

- (void)attachAnimations {
    [self attachPathAnimation];
    [self attachColorAnimation];
}

这是我们如何对图层路径进行动画处理的方法:

- (void)attachPathAnimation {
    CABasicAnimation *animation = [self animationWithKeyPath:@"path"];
    animation.toValue = (__bridge id)[UIBezierPath bezierPathWithOvalInRect:CGRectInset(self.bounds, 4, 4)].CGPath;
    animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    [self.layer addAnimation:animation forKey:animation.keyPath];
}

以下是我们如何为图层填充颜色添加动画效果的方法:

- (void)attachColorAnimation {
    CABasicAnimation *animation = [self animationWithKeyPath:@"fillColor"];
    animation.fromValue = (__bridge id)[UIColor colorWithHue:0 saturation:.9 brightness:.9 alpha:1].CGColor;
    [self.layer addAnimation:animation forKey:animation.keyPath];
}

attach*Animation 方法中的两个方法都使用了一个辅助方法,该方法创建了一个基本动画,并设置为以自动反向和一秒的持续时间无限重复:

- (CABasicAnimation *)animationWithKeyPath:(NSString *)keyPath {
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:keyPath];
    animation.autoreverses = YES;
    animation.repeatCount = HUGE_VALF;
    animation.duration = 1;
    return animation;
}

1
这正是我要找的,但我如何从UIView中调用它以使其出现?我假设这段代码是在它自己的类中设置的。 - bmueller
4
PulseViewUIView 的子类。 - rob mayoff
如何修改以保留视图的最终状态,即更大的圆圈。将animation.repeatCount设置为1,并将animation.autoreverses设置为NO,将会使圆圈动画变大然后立即缩小而不使用动画。我想让圆圈保持大圆形,不返回到其初始状态。有什么建议吗? - hasan
1
@hasan83 看看这个:https://dev59.com/Vmgu5IYBdhLWcg3wLEM9 - WedgeSparda
@WedgeSparda,这已经太老了。但非常感谢你。 - hasan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接