2012-07-13 16 views
17

Ich versuche, den Übergang eines CALayer von normalen Ecken zu abgerundeten Ecken zu animieren. Ich möchte nur die oberen Ecken abrunden, also benutze ich einen UIBezierPath. Hier ist der Code:CABasicAnimation mit CALayer-Pfad animiert nicht

UIRectCorner corners = UIRectCornerTopLeft | UIRectCornerTopRight; 

UIBezierPath* newPath = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:corners cornerRadii:CGSizeMake(8.0f, 8.0f)]; 
UIBezierPath* oldPath = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:corners cornerRadii:CGSizeMake(0.0f, 0.0f)]; 

CAShapeLayer* layer = [CAShapeLayer layer]; 
layer.frame = self.bounds; 
layer.path = oldPath.CGPath; 

self.layer.mask = layer; 

CABasicAnimation* a = [CABasicAnimation animationWithKeyPath:@"path"]; 
[a setDuration:0.4f]; 
[a setFromValue:(id)layer.path]; 
[a setToValue:(id)newPath.CGPath]; 

layer.path = newPath.CGPath; 
[layer addAnimation:a forKey:@"path"]; 

Aber wenn ich dies ausführen, werden die Ecken abgerundet, aber es gibt keine Animations- es sofort passiert. Ich habe ähnliche Fragen hier auf SO gesehen, aber sie haben mein Problem nicht gelöst.

iPhone CALayer animation

Animating CALayer's shadowPath property

Ich bin sicher, dass ich nur eine kleine Sache falsch mache, was das Problem verursacht, sondern für das Leben von mir, ich kann es nicht herausgefunden.

Lösung:

- (void)roundCornersAnimated:(BOOL)animated { 
    UIRectCorner corners = UIRectCornerTopLeft | UIRectCornerTopRight; 

    UIBezierPath* newPath = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:corners cornerRadii:CGSizeMake(8.0f, 8.0f)]; 
    UIBezierPath* oldPath = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:corners cornerRadii:CGSizeMake(0.0001f, 0.0001f)]; 

    CAShapeLayer* layer = [CAShapeLayer layer]; 
    layer.frame = self.bounds; 

    self.layer.mask = layer; 

    if(animated) { 
     CABasicAnimation* a = [CABasicAnimation animationWithKeyPath:@"path"]; 
     [a setDuration:0.4f]; 
     [a setFromValue:(id)oldPath.CGPath]; 
     [a setToValue:(id)newPath.CGPath]; 

     layer.path = newPath.CGPath; 
     [layer addAnimation:a forKey:@"path"]; 
    } else { 
     layer.path = newPath.CGPath; 
    } 
} 

wirklich alles, was ich tun musste, um einen richtigen 'von' Wert für die Animation festgelegt wurde.

+1

Lösung würde anstelle eines Teils der Frage als Antwort schön, aber das ist hilfreich sowieso so ein :) – buildsucceeded

Antwort

10

Es sieht für mich so aus, als ob Sie eine Formebene erstellen, die keinen Pfad hat, und dann versuchen, einen Pfad hinzuzufügen. Form-Layer sind Sonderfälle und funktionieren nicht so.

Sie müssen einen Pfad in der Formebene vor und nach der Animation haben, und der Pfad muss die gleiche Anzahl von Punkten davor und danach enthalten.

Sie müssten einen abgerundeten rechteckigen Pfad mit einem Eckenradius von 0 erstellen (manuell, mit einer Reihe von Seiten und Eckbögen) und dann einen neuen Pfad mit Radien ungleich Null für die Ecken erstellen, die abgerundet werden sollen installiere diesen Pfad als deine Animation.

Auch das funktioniert vielleicht nicht, weil der Pfad genau die gleiche Anzahl von Punkten haben muss, und ich vermute, dass die Bögen zu Punkten vereinfachen würden, wenn der Radius Null ist.

Ich habe gerade einen UIBezierPath-Aufruf gefunden, der ein Rechteck erstellt, in dem Sie auswählen können, welche Ecken gerundet werden sollen. Der Aufruf lautet bezierPathWithRoundedRect: byRoundingCorners: cornerRadiii:

Dadurch wird ein Rechteck mit so vielen abgerundeten Ecken erstellt, wie Sie möchten. Ich bin mir jedoch nicht sicher, ob das für die Pfadanimation funktioniert. Eventuell müssen Sie alle Ecken mit abgerundeten Ecken mit den zwei nicht abgerundeten Ecken, die auf Radius null eingestellt sind, anfordern. Auf diese Weise könnten Sie einen Pfad mit der gleichen Anzahl von Punkten als abgerundeten Rechteckpfad erhalten, damit die Pfadanimation korrekt funktioniert. Du wirst es versuchen müssen.

+0

Danke. Du hattest Recht. Das Einstellen eines korrekten 'von' Wertes für die Animation hat es getan. –

4

Versuchen zu setzen:

layer.path = newPath.CGPath; 

nach:

[layer addAnimation:a forKey:@"path"]; 
Verwandte Themen