Уложите поток, чтобы спать, но продолжайте анимацию - это возможно? - PullRequest
2 голосов
/ 29 сентября 2011

Это может быть странный вопрос, но может быть другое решение для того, чего я пытаюсь достичь, я открыт для всего, что работает как нужно!

Факты:

У меня есть UITableView с UISearchBar, обработанным UISearchDisplayController.

Выше указанного TableView у меня есть несколько кнопок и маленькая UIScrollView.

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

Поэтому я хочу переместить TableView полностью вверх (прикрывая кнопки и ScrollView), когда пользователь начинает поиск.

Мой код и проблема:

- (void)searchDisplayControllerWillBeginSearch:(UISearchDisplayController *)controller {
...

[UIView beginAnimations:@"Search" context:nil];
[UIView setAnimationDuration:0.6];
[self.attractionsTableView setFrame:CGRectMake(0, 0, 320, 400)];
[UIView commitAnimations];

...
return;

}

Теперь проблема заключается в том, что, поскольку расстояние, которое должен пройти мой UITableView, составляет около 100 точек, SearchDisplayController быстрее помещает черное наложение поверх TableView и, таким образом, черное наложение уже сверху, а TableView все еще скользит там.

В результате экран выглядит примерно так:

проблема http://img833.imageshack.us/img833/9186/problemqdu.png

Таким образом, пользователь видит, что TableView скользит вверх (что было бы хорошо), но черный оверлей уже находится там, ожидая, потому что анимация searchDisplayController быстрее, чем у меня.

Итак, у меня есть возможная идея, но я не знаю, как это сделать:

Есть ли способ установить продолжительность анимации searchDisplayController, поместив черный оверлей поверх таблицы поиска?

EDIT:

Я знаю, что могу установить animationDuration на 0,01 или даже 0, но скорость 0,6 кажется вполне приемлемой для расстояния в 100 точек, поэтому я пытаюсь найти другое решение, которое уменьшит продолжительность.

1 Ответ

3 голосов
/ 29 сентября 2011

Хитрость не в том, чтобы цикл выполнения работал нормально до тех пор, пока анимация не будет завершена. Анимации выполняются, когда цикл выполнения работает в определенном режиме. К счастью, оверлейная анимация выполняется в режиме цикла выполнения, отличном от других анимаций, которые запускаются в режиме цикла выполнения по умолчанию. Итак, все, что вам нужно сделать, это запустить цикл выполнения из вашего метода, пока анимация не будет завершена.

- (void)searchDisplayControllerWillBeginSearch:(UISearchDisplayController *)controller {
    BOOL done = NO;
    // Pass the done variable's address as the context so we can be notified
    [UIView beginAnimations:@"SearchExpand" context:&done];
    [UIView setAnimationDelegate:self];
    [UIView setAnimationDidStopSelector:@selector(animationDone:finished:context:)];
    [UIView setAnimationDuration:0.6];
    // Expend the table view to fill its superview
    self.attractionsTableView.frame = [[self.attractionsTableView superview] bounds];
    [UIView commitAnimations];
    NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
    // Run the run loop until the animation completes
    while(!done) {
        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
        if(![runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]])
            break;
        [pool drain];
    }
}

- (void)animationDone:(NSString *)name finished:(NSNumber *)finished context:(void *)context {
    // Set the done flag to YES
    *((BOOL*)context) = YES;
    // and kill the run loop
    CFRunLoopStop(CFRunLoopGetCurrent());
}
...