2012-05-30 60 views
28

我正在使用标准CGContextFillEllipseInRect()代码在我的UIView-drawRect:方法中绘制一个圆。但是,我想稍微发出一些脉冲(变大变小),并用动画改变颜色填充的强度。例如,如果圆圈充满红色,我想用脉冲动作使脉冲圈变红并使其稍微更亮更暗。对Core Animation没有太多经验我对如何做到这一点有点失落,所以任何帮助都将不胜感激。drawRect圆和动画尺寸/颜色

回答

70

如果你不在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; 
} 
+0

非常好的解释。非常感谢:) – Skoota

+1

这正是我正在寻找的,但我怎么从UIView调用它来让它出现?我假设这个代码是在它自己的类中设置的。 – bmueller

+4

'PulseView'是'UIView'的子类。 –