target-c, рандомизация блоков анимации - PullRequest
2 голосов
/ 09 ноября 2011

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

void (^animationOne) (void) = ^{imageOne.center = d;};
void (^afterOne) (BOOL) = ^(BOOL f) {imageOne.center = dOrig;};
[UIView animateWithDuration:.85 delay:3 options:opts animations:animationOne completion:afterOne];

Есть несколько других, которые более или менее придерживаются того же формата. Тем не менее, я бы хотел, чтобы они выглядели случайными. Частично проблема заключается в том, что и анимация, и блоки завершения специфичны друг для друга и являются обязательными, поэтому я не могу просто вставить анимацию в массив, перемешать ее, а затем использовать массив для анимации. Есть ли способ для меня, чтобы рандомизировать это, используя блоки анимации, и если нет, есть ли другой способ сделать это, чтобы я мог рандомизировать порядок? Спасибо.

Редактировать: Благодаря некоторым полезным советам от vikingosegundo, я изменил свой код, чтобы он выглядел так:

 NSArray *animationsCompletions = [NSArray arrayWithObjects:
                                  [NSDictionary dictionaryWithObjectsAndKeys:anim1,@"animation",after1, @"completion", nil],
                                  [NSDictionary dictionaryWithObjectsAndKeys:anim2,@"animation",after2, @"completion", nil],
                                  [NSDictionary dictionaryWithObjectsAndKeys:anim3,@"animation",after3, @"completion", nil],
                                  [NSDictionary dictionaryWithObjectsAndKeys:anim4,@"animation",after4, @"completion", nil],
                                   nil];

NSDictionary *animationCompletionPair = [animationsCompletions randomElement];


[UIView animateWithDuration:.85 delay:3 options:opts animations:[animationCompletionPair objectForKey:@"animation"] completion:[animationCompletionPair objectForKey:@"completion"]];
[UIView animateWithDuration:.85 delay:8 options:opts animations:[animationCompletionPair objectForKey:@"animation"] completion:[animationCompletionPair objectForKey:@"completion"]];
[UIView animateWithDuration:.85 delay:13 options:opts animations:[animationCompletionPair objectForKey:@"animation"] completion:[animationCompletionPair objectForKey:@"completion"]];
[UIView animateWithDuration:.85 delay:18 options:opts animations:[animationCompletionPair objectForKey:@"animation"]completion:[animationCompletionPair objectForKey:@"completion"]];

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

Ответы [ 2 ]

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

Вставьте блоки анимации и завершения в массив (или два).Вместо того, чтобы перемешивать массив, просто случайным образом выбирайте индексы и выполняйте соответствующие блоки анимации.

Например, используя два массива:

NSArray *animations = [NSArray arrayWithObjects:animation1, animation2, animation3, nil];
NSArray *completions = [NSArray arrayWithObjects:completion1, completion2, completion3, nil];
int i = arc4random() % 3;
[UIView animateWithDuration:.85
                      delay:3
                    options:opts
                  animation:[animations objectAtIndex:i]
                 completion:[completions objectAtIndex:i]];

Если вы хотите, чтобы каждая анимация запускалась только один раз,затем создайте второй массив индексов и инициализируйте его числами от 0 до n-1.Затем перемешайте этот массив и выполните итерацию по нему, выполняя анимацию для индекса, который вы найдете в каждой позиции.

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

Ответ Калеба правильный, но вы должны рассмотреть возможность использования метода категории на NSArray для получения случайного элемента, просто чтобы избежать повторения кода и повторного использования проверенного кода.

A [array randomElement]; может выглядеть следующим образом:

-(id)randomElement
{
    if ([self count] < 1) return nil;
    NSUInteger randomIndex = arc4random() % [self count];
    return [self objectAtIndex:randomIndex];
}

Вы найдете эту реализацию и другие удобные инструменты для NSArray в моем arraytools .

В этом случае массив будет заполнен как парой анимаций, так и блоком дополнений в виде пар.

NSArray *animationsCompletions = [NSArray arrayWithObjects:
                                       [NSDictionary dictionaryWithObjectsAndKeys:animation1,@"animation",completion1, @"completion", nil],
                                       [NSDictionary dictionaryWithObjectsAndKeys:animation2,@"animation",completion2, @"completion", nil],
                                       [NSDictionary dictionaryWithObjectsAndKeys:animation3,@"animation",completion3, @"completion", nil],
                                    nil];


NSDictionary *animationCompletionPair = [animationsCompletions randomElement];

[UIView animateWithDuration:.85
                      delay:3
                    options:opts
                  animation:[animationCompletionPair objectForKey:@"animation"]
                 completion:[animationCompletionPair objectForKey:@"completion"]];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...