I want to display a progress HUD right before starting a long task, and dismiss it once the task is done. Right now the UI freezes for some time, then the HUD shows for a second before disappearing. After another 4-5 seconds the task is finished and it displays its results, but the progress HUD is already gone.
- (void) addProcess:(NSString *)searchTerm
{
dispatch_sync(dispatch_get_main_queue(), ^{
UIApplication *app = [UIApplication sharedApplication];
app.networkActivityIndicatorVisible = YES;
[SVProgressHUD showWithMaskType:SVProgressHUDMaskTypeGradient];
});
//DO SOME VERY LONG STUFF HERE
dispatch_sync(dispatch_get_main_queue(), ^{
UIApplication *app = [UIApplication sharedApplication];
app.networkActivityIndicatorVisible = NO;
[SVProgressHUD dismiss];
});
}
I use SVProgressHUD for the progress HUD. I am calling the method addProcess using dispatch_async()
If I use the old +[NSThread detach...], it's working flawlessly, but I don't want to use it anymore.
A couple of things:
The key observation is to always use dispatch_async unless you need dispatch_sync. You don't need synchronous operation here, so just use dispatch_async for your UI updates.
If you're running addProcess from the main queue, it doesn't need to dispatch the first UI update back to the main queue. Obviously, if you're running this from a background queue, you do.
The original question had the dispatch to the background queue within addProcess, which makes more sense to me (keeps all the GCD stuff nicely encapsulated). You've updated your answer to say that you're invoking this via dispatch_async([self addProcess]) (by which I presume you meant to a global queue, not the main queue), which I'm less crazy about. I address both scenarios in my code samples below.
So, in short, if you're invoking this via [self addProcess] (without dispatching that, itself, to the background queue) I'd suggest:
- (void) addProcess:(NSString *)searchTerm
{
UIApplication *app = [UIApplication sharedApplication];
app.networkActivityIndicatorVisible = YES;
[SVProgressHUD showWithMaskType:SVProgressHUDMaskTypeGradient];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//DO SOME VERY LONG STUFF HERE
dispatch_async(dispatch_get_main_queue(), ^{
UIApplication *app = [UIApplication sharedApplication];
app.networkActivityIndicatorVisible = NO;
[SVProgressHUD dismiss];
});
});
}
Or, alternatively,
- (void) addProcess:(NSString *)searchTerm
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
dispatch_async(dispatch_get_main_queue(), ^{
UIApplication *app = [UIApplication sharedApplication];
app.networkActivityIndicatorVisible = YES;
[SVProgressHUD showWithMaskType:SVProgressHUDMaskTypeGradient];
});
//DO SOME VERY LONG STUFF HERE
dispatch_async(dispatch_get_main_queue(), ^{
UIApplication *app = [UIApplication sharedApplication];
app.networkActivityIndicatorVisible = NO;
[SVProgressHUD dismiss];
});
});
}
And if you're doing ...
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self addProcess];
});
then it's just:
- (void) addProcess:(NSString *)searchTerm
{
dispatch_async(dispatch_get_main_queue(), ^{
UIApplication *app = [UIApplication sharedApplication];
app.networkActivityIndicatorVisible = YES;
[SVProgressHUD showWithMaskType:SVProgressHUDMaskTypeGradient];
});
//DO SOME VERY LONG STUFF HERE
dispatch_async(dispatch_get_main_queue(), ^{
UIApplication *app = [UIApplication sharedApplication];
app.networkActivityIndicatorVisible = NO;
[SVProgressHUD dismiss];
});
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With