2013-03-27 17 views
6

Mam dwie animacje rotacji w moim CAAnimationGroup, taki, który zaczyna się od zera, a drugi, który powtarza i autoreverses z tego stanu:Jaka jest maksymalna wartość czasu trwania (CFTimeInterval) dla CAAnimationGroup?

- (void)addWobbleAnimationToView:(UIView *)view amount:(float)amount speed:(float)speed 
{ 
    NSMutableArray *anims = [NSMutableArray array]; 

    // initial wobble 
    CABasicAnimation *startWobble = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; 
    startWobble.toValue = [NSNumber numberWithFloat:-amount]; 
    startWobble.duration = speed/2.0; 
    startWobble.beginTime = 0; 
    startWobble.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 
    [anims addObject:startWobble]; 

    // rest of wobble 
    CABasicAnimation *wobbleAnim = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; 
    wobbleAnim.fromValue = [NSNumber numberWithFloat:-amount]; 
    wobbleAnim.toValue = [NSNumber numberWithFloat:amount]; 
    wobbleAnim.duration = speed; 
    wobbleAnim.beginTime = speed/2.0; 
    wobbleAnim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 
    wobbleAnim.autoreverses = YES; 
    wobbleAnim.repeatCount = INFINITY; 
    [anims addObject:wobbleAnim]; 

    CAAnimationGroup *wobbleGroup = [CAAnimationGroup animation]; 
    wobbleGroup.duration = DBL_MAX; // this stops it from working 
    wobbleGroup.animations = anims; 

    [view.layer addAnimation:wobbleGroup forKey:@"wobble"]; 
} 

Od CFTimeInterval jest zdefiniowany jako podwójne, staram ustawienie czasu trwania grupy animacji do DBL_MAX, ale to zatrzymuje działanie grupy animacji. Jeśli jednak ustawię go na dużą liczbę, na przykład 10000, działa poprawnie. Jaka jest największa liczba, której mogę używać przez okres CAAnimationGroup, aby zapewnić, że będzie działała jak najbliżej nieskończoności?

UPDATE: Wydaje się, że jeśli mogę umieścić w bardzo dużej wartości, takich jak DBL_MAX/4.0 następnie zamarza na sekundę, po czym zaczyna animacji. Jeśli wstawię wartość DBL_MAX/20.0, to zamrożenie na początku jest dużo mniejsze. Wydaje się, że posiadanie tak dużej wartości przez czas trwania powoduje jej zamrożenie. Czy istnieje lepszy sposób robienia tego poza użyciem bardzo dużej wartości w czasie trwania?

+0

Chcesz, aby ta grupa animacji była powtarzana na zawsze? –

+0

Tak, ale chcę tylko, aby druga część grupy powtarzała się na zawsze. – jowie

+0

Czy na pewno chcesz w ogóle ustawić czas trwania? Co stanie się, jeśli nie ustawisz opcji? –

Odpowiedz

1

Mam teraz do czynienia z dokładnie tą samą kwestią ... Mam nadzieję, że ktoś udowodni, że się mylę, ale jedynym rozsądnym sposobem, jaki widzę, aby poradzić sobie z tą sytuacją, jest przeniesienie pierwszej animacji do CATransaction i połączenie jej z animacja autoreverse za pomocą:

[CATransaction setCompletionBlock:block]; 

To nie jest idealne, ale wykonuje swoją pracę.

Jeśli chodzi o pytanie o animacje, które zostały wstrzymane po powrocie z tła, jest to klasyczne ograniczenie struktury CoreAnimation, zaproponowano wiele rozwiązań. Sposób, w jaki go rozwiązuję polega na tym, że po prostu wyszukuje animacje w losowym punkcie animacji, losowo modyfikując właściwość timeOffset. Użytkownik nie może dokładnie określić stanu animacji, ponieważ aplikacja była w tle. Oto kod, który mógłby pomóc (poszukaj komentarzu //RANDOMIZE!!):

[[NSNotificationCenter defaultCenter] addObserver:self 
             selector:@selector(startAnimating) 
              name:UIApplicationWillEnterForegroundNotification 
              object:[UIApplication sharedApplication]]; 

... 

for (CALayer* layer in _layers) 
{ 
    // RANDOMIZE!!! 
    int index = arc4random()%[levels count]; 
    int level = ...; 
    CGFloat xOffset = ...; 

    layer.position = CGPointMake(xOffset, self.bounds.size.height/5.0f + yOffset * level); 

    CGFloat speed = (1.5f + (arc4random() % 40)/10.f); 
    CGFloat duration = (int)((self.bounds.size.width - xOffset)/speed); 

    NSString* keyPath = @"position.x"; 
    CABasicAnimation* anim = [CABasicAnimation animationWithKeyPath:keyPath]; 

    anim.fromValue  = @(xOffset); 
    anim.toValue  = @(self.bounds.size.width); 
    anim.duration  = duration; 
    anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; 
    // RANDOMIZE!! 
    anim.timeOffset  = arc4random() % (int) duration; 
    anim.repeatCount = INFINITY; 

    [layer removeAnimationForKey:keyPath]; 
    [layer addAnimation:anim forKey:keyPath]; 
    [_animatingLayers addObject:layer]; 
} 
0

Jest o wiele prostsze w użyciu pojedynczej animacji klatek kluczowych zamiast grupy dwóch odrębnych animacji.

- (void)addWobbleAnimationToView:(UIView *)view amount:(CGFloat)amount speed:(NSTimeInterval)speed { 
    CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation.z"]; 
    animation.duration = 2 * speed; 
    animation.values = @[ @0.0f, @(-amount), @0.0f, @(amount), @0.0f ]; 
    animation.keyTimes = @[ @0.0, @0.25, @0.5, @0.75, @1.0 ]; 
    CAMediaTimingFunction *easeOut =[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]; 
    CAMediaTimingFunction *easeIn =[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]; 
    animation.timingFunctions = @[ easeOut, easeIn, easeOut, easeIn ]; 
    animation.repeatCount = HUGE_VALF; 
    [view.layer addAnimation:animation forKey:animation.keyPath]; 
} 
Powiązane problemy