开发者

Put a Thread to sleep but keep animations going - is this possible?

This might be a strange question but there might be a different solution for what I'm trying to achieve, I'm open to anything that works as needed!

Facts:

I have a UITableView with a UISearchBar handled by a UISearchDisplayController.

Above said TableView I have some buttons and a small UIScrollView.

When the user taps the SearchBar and the keyboard comes up, there is very little space to show the search results while typing.

Therefore I want to move the TableView all the way to the top (covering the buttons and the ScrollView) when the user begins a search.

My code and the problem:

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

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

...
return;

}

Now the problem is that since the distance my UITableView h开发者_Go百科as to travel is about 100 points, the SearchDisplayController is faster with putting the black overlay on top of the TableView and thus the black overlay is already on top while the TableView is still sliding up there.

The result is a screen that looks kinda like this:

problem http://img833.imageshack.us/img833/9186/problemqdu.png

So the user sees the TableView sliding up (which would be fine) but the black overlay is already up there waiting because the searchDisplayController's animation is faster than mine.

So I have a possible idea but don't know how to do this:

Is there a way to set the duration of the animation of the searchDisplayController putting the black overlay on top of the search tableView?

EDIT:

I know I can set the animationDuration to 0.01 or even 0, but the speed of 0.6 seems pretty ok for a distance of 100 points, so I'm trying to find a different solution that lowering the duration.


The trick is not let the run loop run normally until your animation is done. Animations are performed when the run loop is running in a certain mode. Luckily, the overlay animation is performed in a different run loop mode than other animations, which run in the default run loop mode. So, all you have to do is run the run loop from within your method until the animation is complete.

- (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());
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜