CABasicAnimation mit CALayer-Pfad wird nicht animiert
Ich versuche, die animation der übergang von einem CALayer von normalen Ecken zum abgerundeten Ecken. Ich möchte nur das Runde an den oberen Ecken, so bin ich mit einem UIBezierPath. Hier ist der code:
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 diesen starte, die Ecken sind abgerundet, aber es gibt keine animation - es geschieht sofort. Ich habe gesehen einige ähnliche Fragen hier auf, SO, aber Sie hat nicht mein problem zu lösen.
Animieren CALayer ist shadowPath Eigenschaft
Ich bin mir sicher, ich mache nur eine kleine Sache falsch, die das problem verursacht, aber für das Leben von mir ich kann T es herausfinden.
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 eine korrekte 'aus' - Wert für die animation.
InformationsquelleAutor der Frage eric.mitchell | 2012-07-13
Du musst angemeldet sein, um einen Kommentar abzugeben.
Es sieht für mich so erstellen Sie eine Formebene, die nicht über einen Pfad, dann versuchen zu animieren hinzufügen eines Pfads. Formebenen sind spezielle Fall, und funktionieren nicht so.
Müssen Sie einen Pfad in der Form-Ebene vor und nach der animation, und der Weg muss von der gleichen Anzahl von Punkten, sowohl vor als auch nach.
Müssen Sie erstellen Sie ein abgerundetes Rechteck-Pfad mit einem Eckenradius von 0 (manuell, mit Hilfe einer Reihe von Seiten-und Eck-Bögen), und erstellen Sie dann einen neuen Pfad mit nicht-null-Radien für die Ecken, die Sie abrunden möchten, und installieren Sie diesen Pfad als Ihre animation.
Selbst das könnte nicht funktionieren, obwohl, weil der Weg muss genau die gleiche Anzahl von Punkten, und ich vermute, dass die Bögen vereinfachen würde, um Punkte, wenn der radius null ist.
Fand ich eine UIBezierPath Anruf, erstellen Sie ein Rechteck, wo Sie auswählen können, welche Ecken zu Runden. Der Anruf ist bezierPathWithRoundedRect:byRoundingCorners:cornerRadii:
Wird, erstellen Sie ein Rechteck mit möglichst vielen abgerundeten Ecken, wie Sie möchten. Allerdings bin ich mir nicht sicher, ob es für die Pfad-animation. Sie müssen möglicherweise verlangen Sie alle Ecken werden abgerundet mit den 2 nicht-abgerundeten Ecken auf null gesetzt radius. So KÖNNTEN Sie einen Pfad mit der gleichen Anzahl von Punkten wie ein abgerundetes Rechteck-Pfad, also der Pfad-animation korrekt funktioniert. Sie werde es versuchen.
InformationsquelleAutor der Antwort Duncan C
Versuchen:
nach:
InformationsquelleAutor der Antwort demastyle
Fand eine wirklich elegante Lösung von Andrew Wagner hier.
Esstentially das system behandelt alle Pfade ändern, Animationen, alles, was Sie brauchen, ist:
actionForKey
InformationsquelleAutor der Antwort Harry Bloom