2013-03-27 12 views
6

O durumdan iki rotasyon benim CAAnimationGroup animasyonlar, sıfırdan başlar diğeri tekrarlar başka ve autoreverses vardır:CAAnimationGroup için maksimum süre değeri (CFTimeInterval) nedir?

- (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"]; 
} 

CFTimeInterval çift olarak tanımlanır beri, animasyon grubunun süresini ayarlamayı deneyin DBL_MAX, ancak bu animasyon grubunun çalışmasını durdurur. Ancak, 10000 gibi bir sayıya ayarlıysem iyi çalışır. CAAnimationGroup süresi boyunca kullanabileceğim en büyük sayı, mümkün olduğunca sonsuzluğa yakın çalışmasını sağlamak için nedir?

GÜNCELLEME: Ben böyle DBL_MAX/4.0 olarak çok büyük bir değer koyarsanız o zaman o animasyon başlar, bir saniye donar anlaşılmaktadır. DBL_MAX/20.0 değerini girersem, başlangıçta donma çok daha küçük olur. Süre boyunca böyle büyük bir değere sahip olmanın donmaya neden olduğu görülüyor. Bu süreyi, süre için çok büyük bir değer kullanmaktan daha iyi bir yolu var mı?

+0

Bu animasyon grubunu sonsuza kadar tekrar etmeyi deniyor musunuz? –

+0

evet, ama sadece grubun ikinci kısmının sonsuza kadar tekrarlanmasını istiyorum. – jowie

+0

Süreyi ayarlamanız gerektiğinden emin misiniz? Eğer onu bırakmazsan ne olur? –

cevap

1

Şu anda aynı sorunla karşı karşıyayım ... Umarım birileri bana yanlış olduğunu kanıtlar, ancak bu durumu halledebilmem için tek mantıklı yolu ilk animasyonu CATransaction'a taşımak ve kullanarak autoreverse canlandırma:

[CATransaction setCompletionBlock:block]; 

Bu ideal değil, ancak işi bitirir.

Arka plandan döndüğünüzde duraklatılan animasyonlar hakkındaki sorunuzla ilgili olarak, bu CoreAnimation çerçevesinin klasik bir sınırlamasıdır, bunun için birçok çözüm önerilmiştir. Çözdüğüm yol, animasyonun rastgele bir noktasında animasyonları timeOffset özelliğini rastgele hale getirerek basitçe yeniden yazılmasıdır. Uygulama arka planda olduğu için kullanıcı animasyon durumunun tam olarak ne olduğunu söyleyemez.

[[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

yerine iki ayrı animasyonlar bir grup tek bir kare animasyon kullanmak çok daha kolaydır: Burada yardımcı olabilecek bazı kod (//RANDOMIZE!! yorum için bakmak) 'dir.

- (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]; 
} 
İlgili konular