2012-05-30 8 views
28

Estoy dibujando un círculo en el método -drawRect: de mi UIView usando el código estándar CGContextFillEllipseInRect(). Sin embargo, me gustaría pulir ligeramente (hacer más grande y más pequeño) y cambiar la intensidad del relleno de color con una animación. Por ejemplo, si el círculo está lleno de rojo, me gustaría pulsar el círculo y hacer que el rojo sea ligeramente más claro y más oscuro en el tiempo con la acción de pulsación. Al no tener mucha experiencia con Core Animation, estoy un poco perdido acerca de cómo hacer esto, por lo que cualquier ayuda sería muy apreciada.drawRect círculo y anima tamaño/color

Respuesta

70

Esto es mucho más simple si no dibuja el círculo en drawRect:. En su lugar, configurar el fin de utilizar un CAShapeLayer, así:

@implementation PulseView 

+ (Class)layerClass { 
    return [CAShapeLayer class]; 
} 

El sistema envía layoutSubviews a la vista cada vez que cambia el tamaño (incluso cuando aparece por primera vez). Sobreescribimos layoutSubviews para establecer la forma y la animan:

- (void)layoutSubviews { 
    [self setLayerProperties]; 
    [self attachAnimations]; 
} 

Así es como hemos creado el camino de la capa (que determina su forma) y el color de relleno de la forma:

- (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; 
} 

Necesitamos adjuntar dos animaciones a la capa - una para el camino y uno para el color de relleno:

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

Así es como nos animamos el camino de la capa:

- (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]; 
} 

Así es como animamos color de relleno de la capa:

- (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]; 
} 

Los dos métodos attach*Animation usar un método de ayuda que crea una animación básica y lo configura para repetir indefinidamente con autoreverse y una duración de un segundo :

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

Awesome explanation. Muchas gracias :) – Skoota

+1

Esto es exactamente lo que estoy buscando, pero ¿cómo puedo llamar esto desde una UIView para que aparezca? Supongo que este código está configurado en su propia clase. – bmueller

+4

'PulseView' es una subclase de' UIView'. –

Cuestiones relacionadas