如何在执行冗长的操作时隐藏 UIPopoverController?

Posted

技术标签:

【中文标题】如何在执行冗长的操作时隐藏 UIPopoverController?【英文标题】:How to hide a UIPopoverController while a lengthy operation is to be performed? 【发布时间】:2012-08-27 13:48:39 【问题描述】:

从弹出框控制器中选择一个选项后,代理会被告知已做出选择。

我想关闭弹出框,将其从屏幕上移除,并向用户显示活动指示器。

不幸的是,dismissPopover 下面的代码在 popover 实际消失之前运行,导致长时间等待而没有任何事情发生。

- (void)itemSelected:(int)option 

    [popController dismissPopoverAnimated:YES];

    activityIndicator.hidden = NO;
    [activityIndicator startAnimating];

    switch (option) 
        case 0:
            // Do something that takes some time
            break;

        case 1:
            // Do something that takes even longer
            break;
    


关闭弹出框后,将控制权返回给调用 ViewController 的最佳方法是什么?

【问题讨论】:

【参考方案1】:

问题在于,当您更改 UI 时,它不会立即发生。更改实际上已排队等待下次主事件循环完成时发生。由于这通常会立即发生,因此我们通常不必担心差异。所有 UI 更新都发生在主线程上,并且由于您的长操作也在主线程上,因此在完成长操作之前,应用程序永远不会更新 UI。

一种解决方案是使用 Grand Central Dispatch 将这些操作卸载到另一个线程,这将允许主线程继续执行(并且 UI 继续更新)直到操作完成。

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);

dispatch_async(queue, ^
    [self performReallyLongOperation];
);

dispatch_release(queue);

【讨论】:

我有一个长时间运行的操作,必须在 UI 线程上运行。在开始长时间运行的操作之前,您是否知道有任何方法可以关闭弹出窗口。在主线程上使用 dispatch_asyc 启动长时间运行的操作会导致与 OP 报告的行为相同。 不幸的是,没有。 UIKit 的设置方式,如果你在主线程上运行代码,它不会到达事件循环的末尾并更新 UI。您必须重新检查可以卸载到另一个线程的部分的算法。如果在此过程中需要更新 UI,您可以使用通知或其他类型的挂钩来定期进行这些更新。 做了一些实验,您可以通过将异步调用包装在 dispatch_after 块中来获得所需的效果(等待 100 毫秒左右)...这有效地延迟了异步功能足够的时间让弹出框消失.【参考方案2】:

你可以使用UIPopOverController's delegate方法popoverControllerDidDismissPopover在popover完成dismissing后执行你的代码:

标题

<UIPopoverControllerDelegate>

实施

- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController

    activityIndicator.hidden = NO;
    [activityIndicator startAnimating];

    switch (option) 
        case 0:
            // Do something that takes some time
            break;

        case 1:
            // Do something that takes even longer
            break;
    


【讨论】:

试过了,但由于弹出框是通过编程方式解除的(即用户在弹出框内进行选择),所以不会引发 popoverControllerDidDismissPopover 消息。 @Bill +1 这很有趣。抱歉,我无法提供更多帮助!

以上是关于如何在执行冗长的操作时隐藏 UIPopoverController?的主要内容,如果未能解决你的问题,请参考以下文章

ITSM常见问题之:执行请求过程中如何避冗长的电子邮件会话

如何在执行Facebook喜欢时隐藏“说些什么”的显示

如何在Android应用程序的运行时隐藏(或删除)动作栏[重复]

在使用 cmake 构建时,如何让 make 变得冗长但只有“有意义”的行?

在标签之间切换时执行一些操作?

单击EditText时如何隐藏键盘不显示