Отмена блока в UIView animateWithDuration - PullRequest
4 голосов
/ 20 июля 2011
- (void) startLoading {

    [self blink];
} 

 - (void) blink {  

        [UIView animateWithDuration:0.5
                              delay: 0.0
                            options: UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionCurveEaseOut
                         animations:^{
                            //animate stuff
                         }
                         completion:^(BOOL finished){
                                 [self blink];    
                         }];

}

- (void) stopLoading {
    //What goes here?
}

В моем UIView'е initWithFrame я создаю некоторую графику загрузчика, затем запускаю анимацию загрузчика с [self startLoading].

Вопрос теперь в том, как мне остановить этот «бесконечный цикл».'? или что происходит в методе stopLoading или dealloc, чтобы красиво все разрушить?

Когда я игнорирую тот факт, что блок завершения есть, и просто освобождаю свой UIView изSuper View, все идет хорошо в течение нескольких секунд (больше, чем указано 0,5 секунды), затем приложение вылетает с сообщением:

malloc: * mmap (size = 2097152) не удалось (код ошибки= 12) ошибка: невозможно выделить область ** установить точку останова в malloc_error_break для отладки

У меня есть точка останова в malloc_error_break, и виновником является блок анимации.

Я предполагаю, что UIView был освобожден, будучи удаленным из суперпредставления, и позже выполняется блок завершения, имеющий ссылку на self, это сообщение об освобожденном объекте.

яне могу найти в документации ничего об отмене блока 'в очереди'.

Ответы [ 3 ]

7 голосов
/ 06 декабря 2011

Чтобы отменить, сделайте то же, что и с любой циклической операцией , которую вы хотите отменить: установите флаг, который вы проверяете каждый раз перед циклом.Итак:

- (void) stopLoading {
    kCancel = YES;
}

И теперь ваш блок завершения выглядит следующим образом:

completion:^(BOOL finished){
    if (!kCancel)
        [self blink];    
}];

kCancel может быть иваром, статической глобальной переменной, что угодно.

1 голос
/ 20 июля 2011

UIViewAnimationOptionRepeat имеет магию для вас

[UIView animateWithDuration:0.5
                      delay: 0.0
                    options: UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionCurveEaseOut | UIViewAnimationOptionRepeat
                 animations:^{
                         //animate stuff
                 }
                 completion:^(BOOL finished){
                     NSLog(@"solved ");    
                 }];
0 голосов
/ 19 октября 2012

Я просто повторяю анимацию и через некоторое время убиваю ее с помощью блока отправки:

- (void)animate // Blink a view three times
{
    // We need to stop the animation after a while (0.9 sec)
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 0.9 * NSEC_PER_SEC);
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void)
    {
        [view.layer removeAllAnimations];
        view.alpha = 0.0; // Animation clean-up
    });

    [UIView animateWithDuration:0.15 // 0.15*6=0.9: It will animate six times (three in reverse)
                          delay:0.0
                        options:UIViewAnimationOptionAutoreverse | UIViewAnimationOptionRepeat
                     animations:^{
                         view.alpha = 1.0; // Animation
                     }
                     completion:NULL];
}
...