2013-03-27 18 views
6

tôi có hai hình ảnh động xoay trong CAAnimationGroup của tôi, người ta bắt đầu từ con số không và khác mà lặp đi lặp lại và autoreverses từ trạng thái đó:Giá trị thời lượng tối đa (CFTimeInterval) cho Nhóm CAAnimation là gì?

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

Kể từ CFTimeInterval được định nghĩa là một đôi, tôi cố gắng thiết lập thời gian của nhóm hoạt hình đến DBL_MAX, nhưng điều đó ngăn chặn hoạt ảnh của nhóm hoạt động. Tuy nhiên, nếu tôi đặt nó thành một số lớn, chẳng hạn như 10000, nó chạy tốt. Số lớn nhất mà tôi có thể sử dụng trong khoảng thời gian CAAnimationGroup là gì, để đảm bảo nó có thể hoạt động gần như vô cùng nhất có thể?

CẬP NHẬT: Có vẻ như nếu tôi đặt một giá trị rất lớn như DBL_MAX/4.0 thì nó sẽ đóng băng trong một giây, sau đó bắt đầu hoạt ảnh. Nếu tôi đặt giá trị DBL_MAX/20.0 thì đóng băng lúc đầu sẽ nhỏ hơn rất nhiều. Dường như có một giá trị lớn như vậy trong thời gian này khiến nó bị đóng băng. Có cách nào tốt hơn để làm điều này khác hơn là sử dụng một giá trị rất lớn cho thời gian?

+0

Bạn đang cố gắng làm cho nhóm hoạt ảnh này lặp lại mãi mãi? –

+0

vâng, nhưng tôi chỉ muốn phần thứ hai của nhóm lặp lại mãi mãi. – jowie

+0

Bạn có chắc là bạn cần đặt thời lượng không? Điều gì sẽ xảy ra nếu bạn bỏ nó? –

Trả lời

1

Tôi phải đối mặt với chính xác cùng một vấn đề ngay bây giờ ... Tôi hy vọng một người nào đó chứng minh tôi sai, nhưng cách hợp lý duy nhất tôi thấy để xử lý tình huống này là bằng cách di chuyển hoạt ảnh đầu tiên đến CATransaction và hoạt ảnh tự động sử dụng:

[CATransaction setCompletionBlock:block]; 

Nó không lý tưởng, nhưng hoàn thành công việc.

Về câu hỏi của bạn về hoạt ảnh bị tạm dừng khi quay lại từ nền, đó là hạn chế cổ điển của khung CoreAnimation, nhiều giải pháp đã được đề xuất cho nó. Cách tôi giải quyết nó bằng cách đơn giản đặt lại các hình động tại một điểm ngẫu nhiên của hoạt ảnh, bằng cách ngẫu nhiên thuộc tính timeOffset. Người dùng không thể biết chính xác trạng thái hoạt ảnh là gì, vì ứng dụng ở chế độ nền. Dưới đây là một số mã có thể giúp (tìm //RANDOMIZE!! bình luận):

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

Nó là đơn giản hơn nhiều để sử dụng một hình ảnh động keyframe đơn thay vì một nhóm của hai hình ảnh động riêng biệt.

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