2012-06-19 9 views
5

Sto provando ad animare la larghezza di un rettangolo arrotondato, il problema è quando si passa da larghezza maggiore a larghezza più sottile, l'animazione fa un "salto di aberrazione".(iOS) Come animare il rettangolo arrotondato con shapeLayer?

Ecco il codice:

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

E quando inizio l'animazione:

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

Che cosa sto facendo di sbagliato?

+0

Grazie per la correzione Alexis. – murb83

risposta

3

Fare questo con un CAShapeLayer mi sembra troppo complicato se lo si utilizza solo per un rettangolo arrotondato. Perché non usare semplicemente un CALayer con il set the cornerRadius properly?

L'animazione del fotogramma con angoloRadio impostato funzionerà correttamente.

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

lo anima è fatto semplicemente il concatenamento telaio (non il percorso)

- (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:

Alcune delle proprietà ha cambiato nome come fillColor divenne backgroundColor e la strokeColor e lineWidth sono diventati borderColor e borderWidth ecc.

+0

Grazie! Ma non fa un'animazione, è istantaneo. – murb83

+0

L'ho appena provato. Si anima usando l'animazione di durata 0.3 predefinita. Stai facendo qualcos'altro con il livello? –

+0

Se vuoi personalizzare l'animazione devi farlo esplicitamente –

3

Sebbene proprietà percorso di CAShapeLayer è animatable, non lo fa implicitamente come limiti e la posizione, è necessario fare un'animazione esplicito:

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

Dal momento che probabilmente si desidera che tutte tre le animazioni per accadere insieme, è possibile renderli tutti esplicito e raggruppate:

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"]; 

Se la forma non ha contenuti o bambini, allora si può essere in grado di utilizzare un CALayer invece:

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

Grazie !! Sto testando il tuo codice, te lo dico quando finisci di testare. – murb83

+0

Mi dispiace, ma non funziona bene, penso di fare qualcosa di sbagliato, ma il livello non si sposta dove voglio, penso che il punto di riferimento sia diverso quando faccio l'animazione. Scusa, il mio inglese non è buono. Il modo in cui usi le animazioni è davvero di mio interesse, mi hai aperto un nuovo modo per le animazioni di gruppo. ^^ – murb83

Problemi correlati