2013-03-22 39 views
8

Tôi đang tạo ứng dụng iOS, trong đó tôi có yêu cầu về backgroundColor của chế độ xem để hoạt ảnh thông qua lựa chọn màu sắc. Trong phương thức viewDidLoad của tôi, về cơ bản, tôi khởi chạy một chuỗi các hoạt ảnh UIView bằng cách sử dụng như sau.Cách tốt nhất để xử lý chuỗi hình ảnh động với UIViewAnimations

-(void) beginFirstStageBackgroundAnimation 
{ 
    [UIView animateWithDuration: 3.0f 
          delay: 3.0f 
         options: UIViewAnimationOptionTransitionCrossDissolve 
        animations:^{ 
         self.view.backgroundColor = [UIColor colorWithRed: 251./255 green:203./255 blue:147./255 alpha:1.0]; 
        } 
        completion:^(BOOL finished){ 
         [self secondStageBackgroundAnimation]; 
        } 
    ]; 
} 

Việc xử lý hoàn bắn phương pháp thứ hai có chứa các màu bên cạnh ....

-(void) secondStageBackgroundAnimation 
{ 
    [UIView animateWithDuration: 3.0f 
          delay: 3.0f 
         options: UIViewAnimationOptionTransitionCrossDissolve 
        animations:^{ 
         self.view.backgroundColor = [UIColor colorWithRed:251./255 green:224./255 blue:96./255 alpha:1.0]; 
        } 
        completion:^(BOOL finished){ 
         [self thirdStageBackgroundAnimation]; 
        } 
    ]; 
} 

Và vân vân ... này tiếp tục cho đến khi trong phim hoạt hình thứ bảy tôi gọi [self beginFirstStageBackgroundAnimation]; trong việc hoàn thành để bắt đầu lại quá trình.

Khi tôi rời khỏi chế độ xem với nút quay lại, trong chế độ xemDidDisappear hoặc khi bộ hẹn giờ trên màn hình kết thúc, tôi chạy [self.view.layer removeAllAnimations]; để loại bỏ hoàn toàn hoạt ảnh. Tuy nhiên, ứng dụng chạy và hoạt động chính xác như dự định nhưng dường như bị lỗi sau khi rời khỏi chế độ xem và chạy cho toàn bộ và mặc dù tôi không biết tại sao dường như có liên quan đến chuỗi hoạt ảnh này.

Có giải pháp nào tốt hơn để tạo hiệu ứng backgroundColor của chế độ xem sau mỗi 3 giây với thời gian trễ là 3 giây không?

Và không [self.view.layer removeAllAnimations]; thực sự làm những gì tôi muốn?

EDIT: Mã nơi tôi rời khỏi cái nhìn như sau:

-(void) backBtnPressed:(id)sender 
{ 
    [self stopAudio]; // stop audio that is playing. 
    [self.view.layer removeAllAnimations]; // remove all animations? 
    [self.navigationController popViewControllerAnimated: YES]; // pop view from stack 
} 
+0

Tôi không chắc chắn rằng removeAllAnimations dừng hoạt ảnh của bạn, hình động được đính kèm với lớp và bạn không trực tiếp sử dụng hoạt ảnh lớp, nhưng hoạt ảnh UIView ... dù sao nó cũng không bị sập, bạn có thể gọi nó ngay cả mà không gọi bất kỳ hoạt hình nào cả. nhật ký của bạn sau sự cố là gì? – meronix

+1

+1 sự nguy hiểm thực sự ở đây là cuộn lên ngăn xếp trong một vòng lặp mỗi ba giây - về cơ bản là một đệ quy chậm lớn. câu trả lời bạn chấp nhận tránh điều đó, cũng như của riêng tôi. Tôi chắc chắn câu trả lời được chấp nhận là tốt, mặc dù đó là sở thích của tôi để gắn bó với các khối bất cứ nơi nào có thể. – danh

Trả lời

5

Bạn có thể cố gắng sử dụng CAAnimation Tôi nghĩ rằng nó sẽ được dễ dàng hơn cho bạn để quản lý màu sắc và hình ảnh động

- (void)viewDidAppear:(BOOL)animated 
{ 
    [super viewDidAppear:animated]; 
    NSArray *colors = @[[UIColor greenColor], 
         [UIColor redColor], 
         [UIColor blueColor], 
         [UIColor yellowColor], 
         [UIColor orangeColor] 
         ]; 
    NSMutableArray *animations = [NSMutableArray new]; 
    float colorAnimationDuration = 3.0f; 
    for (int i = 0; i < colors.count; i++) 
    { 
     CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"backgroundColor"]; 
     animation.toValue = (id)[[colors objectAtIndex:i] CGColor]; 
     animation.duration = colorAnimationDuration; 
     animation.beginTime = i * colorAnimationDuration; 
     animation.removedOnCompletion = NO; 
     animation.fillMode = kCAFillModeForwards; 

     [animations addObject:animation]; 
    } 

    CAAnimationGroup *animationsGroup = [CAAnimationGroup new]; 
    animationsGroup.duration = colors.count * colorAnimationDuration; 
    animationsGroup.repeatCount = HUGE_VALF; 
    animationsGroup.animations = animations; 

    [self.view.layer addAnimation:animationsGroup forKey:@"myAnimations"]; 

} 

- (void)viewWillDisappear:(BOOL)animated 
{ 
    [super viewWillDisappear:animated]; 
    [self.view.layer removeAnimationForKey:@"myAnimations"]; 
} 
+0

Dường như hoạt động hoàn hảo. Đánh giá cao rằng –

-1

cố gắng để thêm một tấm séc trong mọi phương pháp hoạt hình, như thế này:

-(void) secondStageBackgroundAnimation 
{ 
if (self.view.superview){ 
    [UIView animateWithDuration: 3.0f 
          delay: 3.0f 
         options: UIViewAnimationOptionTransitionCrossDissolve 
        animations:^{ 
         self.view.backgroundColor = [UIColor colorWithRed:251./255 green:224./255 blue:96./255 alpha:1.0]; 
        } 
        completion:^(BOOL finished){ 
         [self thirdStageBackgroundAnimation]; 
        } 
    ]; 
} 
} 

bạn có thể gửi mã nơi bạn "để lại quan điểm với nút quay lại"? vấn đề có thể có mặt ở đó ...

+0

Câu hỏi đã được chỉnh sửa. Mã được đăng theo yêu cầu –

7

Tôi nghĩ rằng con đường để đi là đại diện cho những gì bạn muốn xảy ra trong mỗi hoạt ảnh theo tham số (trong trường hợp này chỉ là một màu), và sau đó giữ các tham số đó trong một mảng. Mảng giống như danh sách công việc phải làm của bạn:

@property(strong, nonatomic) NSArray *animationTodo; 

Chúng tôi cũng cần theo dõi vị trí chúng tôi có trong danh sách. Sử dụng một (NS) số đóng hộp vì vậy chúng tôi có thể đại diện "không động" như một con số không, khác biệt với chỉ số zero:

@property(strong, nonatomic) NSNumber *animationIndex; 

Mảng được khởi tạo với màu sắc:

self.animationTodo = [NSArray arrayWithObjects:[UIColor redColor], [UIColor greenColor], ... nil]; 

Bây giờ hình ảnh động có thể được nén đến một phương pháp duy nhất:

- (void)animate { 

    if (!animationIndex) return; 
    NSInteger index = [animationIndex intValue]; 
    [UIView animateWithDuration:3.0 animations:^{ 
     self.view.backgroundColor = [animationToDo objectAtIndex:index]; 
    } completion:^(BOOL finished) { 
     NSInteger nextIndex = (index==self.animationTodo.count-1)? 0 : index+1; // advance index in a ring 
     self.animationIndex = [NSNumber numberWithInt:nextIndex]; 
     // schedule the next one in 3s 
     [self performSelector:@selector(animate) withObject:nil afterDelay:3.0]; 
    }]; 
} 

Thực hiện chọn bạn hãy nêu sự chậm trễ và cũng có tác dụng tích cực của không quanh co lên stack mỗi lần bạn khởi động hoạt hình tiếp theo.

Dừng cũng thật đơn giản. Làm điều này trước khi khung nhìn biến mất và bất kỳ lúc nào bạn muốn dừng lại.

- (void)stopAnimating { 

    self.animationIndex = nil; 
    [NSObject cancelPreviousPerformRequestsWithTarget:self]; 
} 
+1

Chỉ cần nhìn thấy câu trả lời này. Tôi đã đi với các giải pháp từ câu trả lời chấp nhận, mà hoạt động hoàn hảo cho nhu cầu của tôi. Tuy nhiên, đây cũng là một cách tuyệt vời và không phải thứ tôi đã từng cân nhắc. –