让线程进入睡眠状态但保持动画继续 - 这可能吗?

发布于 2024-12-06 22:44:15 字数 1326 浏览 0 评论 0原文

这可能是一个奇怪的问题,但对于我想要实现的目标可能有不同的解决方案,我对任何根据需要起作用的东西持开放态度!

事实:

我有一个 UITableView 和一个由 UISearchDisplayController 处理的 UISearchBar

上面说的 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 仍在向上滑动时,overlay 已经在顶部了。

结果是一个看起来有点像这样的屏幕:

问题http://img833.imageshack。 us/img833/9186/problemqdu.png

因此,用户看到 TableView 向上滑动(这很好),但黑色覆盖层是已经在那里等待了,因为 searchDisplayController 的动画比我的快。

所以我有一个可能的想法,但不知道该怎么做:

有没有办法设置 searchDisplayController 的动画持续时间,将黑色覆盖层放在搜索 tableView 的顶部?

编辑:

我知道我可以将animationDuration设置为0.01甚至0,​​但是对于100点的距离来说0.6的速度似乎相当不错,所以我试图找到一个不同的解决方案来降低持续时间。

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 has 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

明天过后 2024-12-13 22:44:15

诀窍是在动画完成之前不要让运行循环正常运行。当运行循环以某种模式运行时执行动画。幸运的是,覆盖动画是在与其他动画不同的运行循环模式下执行的,其他动画在默认运行循环模式下运行。因此,您所要做的就是从方法内运行运行循环,直到动画完成。

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

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());
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文