Остановка всех анимаций, выполняемых в другом потоке - PullRequest
5 голосов
/ 06 ноября 2011

У меня есть меню с элементами, появляющимися сразу после одного с интервалом в 3 секунды, я делаю это так:

for(UIButton *menuItem in menuItems){
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (0.3 * i) * NSEC_PER_SEC), dispatch_get_current_queue(), ^{
        [menuItem setAlpha:1.0];
    }                             
}

Можно ли остановить анимацию в середине (когдакнопка нажата, например)?Я попытался просто установить все в альфа 1.0, но, как и ожидалось, потоки продолжали работать и снова показывали элементы.

Буду признателен за любые идеи :)Шай.

Ответы [ 3 ]

3 голосов
/ 16 ноября 2011

Вы можете создавать анимации, используя блочную анимацию UIView, с установленным delay:.Никакая нить не беспокоит там.

Эти анимации можно прервать, запустив другую блочную анимацию с установленным параметром UIViewAnimationOptionBeginFromCurrentState.

Для альфа-переходов это хорошо, так как это не имеет значениякакова текущая позиция анимации.Если вы перемещаете объекты, вы можете получить текущую позицию, запросив view.layer.presentationLayer, которая содержит текущее состояние объекта.Вам нужно будет импортировать платформу QuartzCore, чтобы сделать это.Это также дает вам метод, removeAllAnimations, который будет в значительной степени выполнять то, на что это похоже, и переводит любое представление прямо в конечную точку любой анимации, которую он ожидает или ожидает.

1 голос
/ 16 ноября 2011

Не думаю, что вы можете остановить анимацию, уже запланированную. Но вы можете установить переменную экземпляра с флагом BOOL, указывающим, была ли кнопка уже нажата или нет.

Например, предположим, что целью вашей кнопки является метод buttonTapped.

Инициализируйте ваш флаг на NO.

- (id)init {
    if (self = [super init]) {
        buttonAlreadyTapped = NO;
    }

    return self;
}

В целях вашей кнопки установите флаг YES.

- (void)buttonTapped {
    self.buttonAlreadyTapped = YES;
}

И изменять alpha только если флаг NO.

for (NSInteger i = 1; i <= [menuItems count]; i++) {        
    UIButton *menuItem = [menuItems objectAtIndex:i-1];

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (3 * i) * NSEC_PER_SEC), dispatch_get_current_queue(), ^{
        if (!self.buttonAlreadyTapped) {
            menuItem.alpha = 1.0f;
        }
    });
}

Помните, что отправка сообщений на UIKit должна всегда выполняться в главном потоке.

for (NSInteger i = 1; i <= [menuItems count]; i++) {        
    UIButton *menuItem = [menuItems objectAtIndex:i-1];

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (3 * i) * NSEC_PER_SEC), dispatch_get_current_queue(), ^{
        if (!self.buttonAlreadyTapped) {
            dispatch_async(dispatch_get_main_queue(), ^{
                menuItem.alpha = 1.0f;
            });
        }
    });
}
0 голосов
/ 16 ноября 2011

Может быть, вы найдете ответ в этом ответе, и, возможно, вы сделаете свое дело другим способом.

...