2014-05-22 7 views
5

Ich versuche, eine interaktive Animation zu erstellen, die speed von 0.0 verwendet und die timeOffset-Eigenschaft als Reaktion auf Benutzeraktionen bearbeitet. Ich möchte, dass sich der Anfangszustand der Animation irgendwo in der Mitte der definierten Animation befindet, da die Benutzeraktion es der Animation ermöglicht, vom Anfangspunkt aus sowohl vorwärts als auch rückwärts zu gehen.Wie kann ich eine interaktive Animation zu einem beliebigen Zeitversatz starten?

Hier ist ein Beispielcode, der ein vereinfachter Fall von dem ist, was ich versuche zu tun.

@interface TestViewController : UIViewController {} 
@property (strong, nonatomic) IBOutlet UIView * transformerView; 
@property (strong, nonatomic) IBOutlet UISlider * slider; 
@end 

@implementation TCTestViewController {} 

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    self.slider.minimumValue = 0.0f; 
    self.slider.maximumValue = 1.0f; 
    self.slider.value = 0.5f; 

    CABasicAnimation * animation = [CABasicAnimation animationWithKeyPath:@"transform"]; 
    animation.fromValue = [NSValue valueWithCATransform3D:CATransform3DMakeTranslation(-320.0f, 0.0f, 0.0f)]; 
    animation.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeTranslation(320.0f, 0.0f, 0.0f)]; 
    animation.duration = 1.0f; 

    self.transformerView.layer.speed = 0.0; 
    [self.transformerView.layer addAnimation:animation forKey:@"test"]; 

    // *** THIS IS THE PROBLEM LINE *** 
    self.transformerView.layer.timeOffset = 0.5; 
} 

- (IBAction)onSliderValueChanged { 
    self.transformerView.layer.timeOffset = self.slider.value; 
} 

@end 

Dieser View-Controller hat einen Blick mir eine Animation bin hinzufügen, die in der X-Achse von -320pt bis + 320pt übersetzen, und ich will es in der Mitte beginnen, so dass keine Übersetzung gibt, bis den Benutzer ist interagiert mit ihm. Ich habe auch einen Schieberegler, der, wenn er geändert wird, die timeOffset-Eigenschaft so einstellt, dass sie der Position des Schiebereglers entspricht.

Wenn ich die Problem-Zeile weglassen, wo auf 0,5 eingestellt ist, funktioniert alles wie erwartet, aber die Ansicht beginnt mit -320pt übersetzt. Es verfolgt dann den Schieberegler von diesem Punkt an richtig.

Wenn die Problemleitung da ist, geht alles schief. Die Ansicht beginnt immer noch mit -320pt übersetzt und verfolgt den Schieberegler nur, wenn der Schiebereglerwert über 0,5 liegt. Selbst dann geht die Übersetzung nur von -320pt nach 0pt und wird nie höher übersetzt. Für Schiebereglerwerte unter 0,5 gibt es überhaupt keine Übersetzung.

Es macht keinen Unterschied, ob ich die Problemlinie vor oder nach dem Hinzufügen der Animation zum Layer platziere. Was hilft, wenn ich -performSelector:withObject:afterDelay mit einer Verzögerung von 0.0 verwende, um die ursprüngliche auf eine zukünftige Iteration der Laufschleife einzustellen, aber bevor der Benutzer mit dem Schieberegler interagiert. Leider ist diese Problemumgehung für das reale Projekt nicht praktikabel, da ich die Animation im laufenden Betrieb erstellen muss, wenn der Benutzer die Interaktion startet.

Warum funktioniert die timeOffset-Eigenschaft nicht, wenn sie in der gleichen Iteration der Ausführungsschleife festgelegt wurde, als die Animation zum Layer hinzugefügt wurde? Ich denke, dass, wenn die zu dieser Zeit festgelegt wird, es eine neue Basiszeit für die Animation wird.

Kann jemand eine Möglichkeit vorschlagen, dass ich eine Animation erstellen kann, die interaktiv mit der -Eigenschaft gemacht werden kann, und sie so einstellen, dass sie an einer anderen Stelle als am Anfang startet?

+0

@ Matt - Guter Gedanke, aber in dem ursprünglichen Projekt diese Probe in einem anderen Verfahren angepasst wurde das Problem aufgetreten ist aus, die gut nach viewDidLoad genannt wurde. – GBegen

Antwort

1

Ich würde versuchen, die folgenden:

dispatch_async(dispatch_get_main_queue(), ^{ 
    self.transformerView.layer.timeOffset = 0.5; 
});