2012-05-30 3 views
28

Я рисую круг в методе -drawRect: моего UIView, используя стандартный код CGContextFillEllipseInRect(). Тем не менее, я хотел бы слегка пульсировать (делать все больше и меньше) и изменять интенсивность заливки цвета анимацией. Например, если круг заполнен красным, я хотел бы пульсировать круг и сделать красное чуть светлее и темнее вовремя с пульсирующим действием. Не имея большого опыта работы с 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 методов используют вспомогательный метод, который создает основную анимацию и устанавливает его повторять до бесконечности с AutoReverse и один вторым сроком :

- (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'. –