我想要实现的目标:
使用一些自定义图标,标签等创建处理屏幕,并具有以下行为。
在窗口上添加视图,该视图不允许用户在删除之前触摸应用程序中的任何内容。 (如处理/加载屏幕)
当显示此视图时,所有其他操作(如添加子视图,执行segue等)应该正常工作但在我的加载视图下方。
希望方法showProcessingScreen能够在任何线程上工作(无论是哪种线程切换代码都应该在各自的show / hide方法中)。
代码:
-(void) showProcessingScreen
{
dispatch_async(dispatch_get_main_queue(),
^{
UIStoryboard *mystoryboard = [UIStoryboard storyboardWithName:@"Main_iPhone" bundle:nil];
processingScreen = [mystoryboard instantiateViewControllerWithIdentifier:@"loadingViewController"];
UIWindow* mainWindow = [[UIApplication sharedApplication] keyWindow];
[mainWindow addSubview: processingScreen.view];
[mainWindow bringSubviewToFront:processingScreen.view];
});
}
-(void) hideProcessingScreen
{
dispatch_async(dispatch_get_main_queue(),
^{
[processingScreen.view removeFromSuperview];
});
}
问题:
我希望上面的代码可以立即显示/隐藏加载屏幕。
- (IBAction)proceedBtnPressed:(id)sender
{
[[GUIUtilities sharedObj] showProcessingScreen];
//Some other code here
}
当我像上面一样调用showProcessingScreen时,处理屏幕大约需要2-3秒才能显示。 但当我删除它下面的其他代码(//其他一些代码)时,它会立即显示屏幕。
我尝试了什么:
//代码
-(IBAction)proceedBtnPressed:(id)sender
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0),
^{
[[GUIUtilities sharedObj] showProcessingScreen];
//Some other code here
});
}
但我不想在showProcessingScreen之外使用任何线程切换机制。
这是几乎在每个应用程序中使用的常见屏幕。我在xib中使用了类似的代码,我以前的应用程序中的自定义视图没有使用故事板等, 我知道这与线程有关,我在这里做错了什么?实现这一目标的最佳做法是什么? 任何帮助都将是aprreciatead。
答案 0 :(得分:0)
你可以试试这个:
- (void)doSomeOtherCode {
//Some other code here
}
- (IBAction) showProcessingScreenAndDoSomeOtherCode:(id)sender
{
[[GUIUtilities sharedObj] showProcessingScreen];
[self performSelector:@selector(doSomeOtherCode) withObject:nil afterDelay:0.0];
}
- (IBAction)proceedBtnPressed:(id)sender
{
[self showProcessingScreenAndDoSomeOtherCode:self];
}
它会起作用。关于你的评论:
但我不想在showProcessingScreen之外使用任何线程切换机制。
上述解决方案不会导致任何线程切换到showProcessingScreen
之外。 performSelector
只会在事件循环队列中添加一个条目。
编辑:
如果使用块,可以通过以下方式获得相同的结果:
dispatch_async(dispatch_get_main_queue(),
^{
[[GUIUtilities sharedObj] showProcessingScreen];
dispatch_async(dispatch_get_main_queue(), ^{
//Some other code here
});
});
或:
dispatch_async(dispatch_get_main_queue(),
^{
[[GUIUtilities sharedObj] showProcessingScreen];
});
dispatch_async(dispatch_get_main_queue(), ^{
//Some other code here
});
由于主队列是一个串行队列,showProcessingScreen
和“此处的其他一些代码”将以串行方式执行。
答案 1 :(得分:0)
问题在于,当您进行调度时,您会在运行循环结束时创建加载视图。无论你的“其他代码”是什么阻塞主线程几秒钟。
如果您将此“其他代码”移至其他主题,则可以解决您的问题。 (这个解决方案很理想。)
你也可以只有条件地切换到主线程,如果你从主线程调用加载视图,这将解决问题:
-(void) showProcessingScreen
{
if (![NSThread isMainThread]) {
[self performSelectorOnMainThread:@selector(showProcessingScreen) withObject:nil waitUntilDone:FALSE];
return;
}
UIStoryboard *mystoryboard = [UIStoryboard storyboardWithName:@"Main_iPhone" bundle:nil];
processingScreen = [mystoryboard instantiateViewControllerWithIdentifier:@"loadingViewController"];
UIWindow* mainWindow = [[UIApplication sharedApplication] keyWindow];
[mainWindow addSubview: processingScreen.view];
[mainWindow bringSubviewToFront:processingScreen.view];
}
答案 2 :(得分:0)
您可以直接调用
,而不是添加拦截触摸事件的叠加视图– beginIgnoringInteractionEvents
– endIgnoringInteractionEvents