如何在执行冗长的操作时隐藏 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?的主要内容,如果未能解决你的问题,请参考以下文章
如何在Android应用程序的运行时隐藏(或删除)动作栏[重复]