2016-10-13 1 views
1

Ich ändere CAShapeLayer 's Pfad in for Schleife, aber es zeigt nur das letzte Ergebnis der Schleife. Ich weiß, dass ich das mit CABasicAnimation tun kann, aber ich muss den Weg auf diese Weise ändern. Irgendwelche Ideen, wie man das macht?Das Ändern des Pfads von CAShapeLayer in for-Schleife macht keinen Effekt

UIBezierPath *path = [ShapeManager getCirclePathAppendedWithCirclePathWithRadius:radius 
                     andFrame:self.view.bounds]; 
self.layer.fillRule = kCAFillRuleEvenOdd; 
self.layer.fillColor = [UIColor grayColor].CGColor; 
self.layer.opacity = 0.5; 
self.layer.path = path.CGPath; 
[self.view.layer addSublayer:self.layer]; 
for (int i = 1; i < 100; ++i) { 
    path = [ShapeManager getCirclePathAppendedWithCirclePathWithRadius:self.view.bounds.size.width-i 
                   andFrame:self.view.bounds]; 
    self.layer.path = path.CGPath; 
} 

Hilfsmethoden

+ (UIBezierPath *)getCirclePathAppendedWithCirclePathWithRadius:(CGFloat)radius andFrame:(CGRect)frame { 
    UIBezierPath *backgroundPath = [UIBezierPath bezierPathWithRect:frame]; 
    [backgroundPath appendPath:[self getCirclePathWithRadius:radius andFrame:frame]]; 
    return backgroundPath; 
} 

+ (UIBezierPath *)getCirclePathWithRadius:(CGFloat)radius andFrame:(CGRect)frame { 
    CGRect rect = frame; 
    UIBezierPath *circlePath; 
    circlePath = [UIBezierPath bezierPathWithArcCenter:(CGPoint){rect.size.width/2, rect.size.height/2} radius:radius startAngle:0 endAngle:M_PI*2 clockwise:YES]; 
    return circlePath; 
} 
+0

Was werden Sie mit dieser for-Schleife erreichen? Es wird nichts animieren. Wenn Sie eine Variable millionenfach setzen, haben Sie am Ende nur den letzten Wert, oder? Das gleiche hier – alexburtnik

+0

ich versuche, das Layout abhängig von einer Geräteposition (mit CoreMotion) zu zeichnen. – passingnil

Antwort

1

Sie haben Recht über CABasicAnimation verwenden.

  1. Entfernen Sie Ihre for Schleife, es wird nicht die Aufgabe erledigen.
  2. Fügen Sie CABasicAnimation für path Schlüssel mit Werten hinzu, zwischen denen interpoliert werden soll.

UIBezierPath *fromPath = [self.class getCirclePathAppendedWithCirclePathWithRadius:self.view.bounds.size.width andFrame:self.view.bounds]; 
UIBezierPath *toPath = [self.class getCirclePathAppendedWithCirclePathWithRadius:self.view.bounds.size.width-99 andFrame:self.view.bounds]; 

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

[layer addAnimation:animation forKey:@"pathAnimation"]; 
layer.speed = 0; 

Update::

  1. In der letzten Zeile setzen Sie speed Wert Dieser Code sollte nur einmal in viewDidLoad Methode aufgerufen werden 0, weil Sie den Animationsfortschritt manuell einstellen möchten:

@property (nonatomic, assign) double progress; 

- (void) setProgress: (double) progress { 
    _progress = progress;   
    layer.timeOffset = (CFTimeInterval)progress; 
} 

Dies setzt voraus, dass die Animationsdauer 1,0 ist. Andernfalls müssen Sie

setzen
layer.timeOffset = (CFTimeInterval)(progress * totalDuration); 

Jetzt nur Fortschritt im Bewegungsrückruf entsprechend dem aktualisierten Wert setzen.

+0

Ich habe das versucht. Aber ich muss ui je nach Geräteposition zeichnen. Ich empfange Gerätebewegungsaktualisierungen ungefähr mit 0.01time interval, und ich muss Animationen sehr schnell tun – passingnil

+0

So möchtest du Pfad entsprechend Bewegungswert jedesmal aktualisieren, wenn dein Rückruf gerufen wird (~ 60times pro Sekunde)? – alexburtnik

+0

Ja, das brauche ich – passingnil

Verwandte Themen