2012-06-19 19 views
5

Estoy tratando de animar el ancho de un rectángulo redondeado, el problema es cuando se pasa de un ancho mayor a un ancho más delgado, la animación realiza un "salto de aberración fácil".(iOS) Cómo animar un rectángulo redondeado con shapeLayer?

Aquí está el código:

shapeLayer = [CAShapeLayer layer]; 
shapeRect = CGRectMake(0.0f, 0.0f, 150.0f, 200.0f); 
[shapeLayer setBounds:shapeRect]; 
[shapeLayer setPosition:CGPointMake(iniPosX, 80.0f)]; 
[shapeLayer setFillColor:[[UIColor blackColor] CGColor]]; 
[shapeLayer setStrokeColor:[[UIColor clearColor] CGColor]]; 
[shapeLayer setLineWidth:1.0f]; 
[shapeLayer setLineJoin:kCALineJoinRound]; 
[shapeLayer setOpacity:0.2]; 
path = [UIBezierPath bezierPathWithRoundedRect:shapeRect cornerRadius:15.0]; 
[shapeLayer setPath:path.CGPath]; 
[self.layer addSublayer:shapeLayer]; 

Y cuando comienzo la animación:

- (void)adjustSelectorToPosAndSize:(float)posX andWidth:(float)width 
{ 
    shapeRect = CGRectMake(0.0f, 0.0f, width, 200.0f); 
    [shapeLayer setBounds:shapeRect]; 
    [shapeLayer setPosition:CGPointMake(posX, 80.0f)]; 
    path = [UIBezierPath bezierPathWithRoundedRect:shapeRect cornerRadius:15.0]; 
    [shapeLayer setPath:path.CGPath]; 
} 

¿Qué estoy haciendo mal?

+0

Gracias por la corrección Alexis. – murb83

Respuesta

3

Hacer esto con un CAShapeLayer me parece demasiado complicado si solo lo usa para un rectángulo redondeado. ¿Por qué no simplemente usar un CALayer con el conjunto the cornerRadius properly?

Animar el marco con la esquinaEl conjunto de Raid funcionará bien.

myLayer = [CALayer layer]; 
shapeRect = CGRectMake(0.0f, 0.0f, 150.0f, 200.0f); 
[myLayer setBounds:shapeRect]; 
[myLayer setPosition:CGPointMake(iniPosX, 80.0f)]; 
[myLayer setBackgroundColor:[[UIColor blackColor] CGColor]]; 
[myLayer setBorderColor:[[UIColor clearColor] CGColor]]; 
[myLayer setBorderWidth:1.0f]; 
[myLayer setOpacity:0.2]; 
[myLayer setCornerRadius:15.0]; 
[self.layer addSublayer:myLayer]; 

la animación que se hace simplemente encadenar el marco (no el camino)

- (void)adjustSelectorToPosAndSize:(float)posX andWidth:(float)width 
{ 
    shapeRect = CGRectMake(0.0f, 0.0f, width, 200.0f); 
    [myLayer setBounds:shapeRect]; 
    [myLayer setPosition:CGPointMake(posX, 80.0f)]; 
} 

Importante:

Algunas de las propiedades cambiado de nombre como fillColor convirtió backgroundColor y la strokeColor y lineWidth se convirtió en borderColor y borderWidth etc.

+0

¡Gracias! Pero no hace una animación, es instantáneo. – murb83

+0

Acabo de intentarlo. Se anima utilizando la animación de duración predeterminada de 0,3. ¿Estás haciendo algo más con la capa? –

+0

Si desea personalizar la animación, debe hacerlo explícitamente –

3

Aunque la propiedad ruta de CAShapeLayer es animatable, que no lo hace de forma implícita como límites y posición, usted tiene que hacer una animación explícita:

CABasicAnimation* anim = [CABasicAnimation animationWithKeyPath: @"path"]; 
anim.fromValue = (id) fromPath.CGPath; 
anim.toValue = (id) toPath.CGPath; 
anim.duration = 1.0; 
[layer addAnimation: anim forKey: @“resize”]; 

Dado que es probable que desee los tres animaciones a pasar juntos, se pueden hacer que todos explícita y agrupan:

CABasicAnimation* anim1 = [CABasicAnimation animationWithKeyPath: @"position"]; 
anim1.fromValue = [NSValue valueWithCGPoint: fromPosition]; 
anim1.toValue = [NSValue valueWithCGPoint: toPosition]; 
anim1.duration = 1.0; 

CABasicAnimation* anim2 = [CABasicAnimation animationWithKeyPath: @"bounds"]; 
anim2.fromValue = [NSValue valueWithCGRect: fromBounds]; 
anim2.toValue = [NSValue valueWithCGRect: toBounds]; 
anim2.duration = 1.0; 

CABasicAnimation* anim3 = [CABasicAnimation animationWithKeyPath: @"path"]; 
anim3.fromValue = (id) fromPath.CGPath; 
anim3.toValue = (id) toPath.CGPath; 
anim3.duration = 1.0; 

CAAnimationGroup* animG = [CAAnimationGroup animation]; 
animG.animations = [NSArray arrayWithObjects: anim1, anim2, anim3, nil]; 
animG.duration = 1.0; 
[layer addAnimation: animG forKey:@"resize"]; 

Si su forma no tiene contenido o hijos, entonces es posible que pueda usar una vez CALayer:

CALayer* rectLayer = [CALayer layer]; 
rectLayer.masksToBounds = YES; 
rectLayer.bounds = startBounds; 
rectLayer.backgroundColor = [[UIColor blackColor] CGColor]; 
rectLayer.cornerRadius = 15.0; 
[self.layer addSublayer: rectLayer]; 

// Then later implicitly animate the bounds: 
rectLayer.bounds = newBounds; 
+0

¡Gracias! Estoy probando tu código, te digo cuándo terminas las pruebas. – murb83

+0

Lo siento, pero no funciona bien, creo que estoy haciendo algo mal, pero la capa no se mueve a donde quiero, creo que el punto de referencia es diferente cuando hago la animación. Lo siento, mi inglés no es bueno. La forma en que usas las animaciones es realmente de mi interés, me abriste una nueva forma en las animaciones grupales. ^^ – murb83

Cuestiones relacionadas