Search code examples
iosuialertviewdispatch-async

Cant dismiss UIAlertView, buttons not clickable


I have the following code where i show a MBProgress view and then run code in a separate thread. I then get a handle to the main thread and dismiss the spinner which works and then i show a UIAlertView. The UIAlertView loads fine however i can not click any of the buttons. If the alert view is outside of the dispatch block it works fine. Any ideas?

[MBProgressHUD showHUDAddedTo:self.view animated:YES];
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{

    // Do something...
    GamePlayManager *gameManager = [GamePlayManager alloc];
    Session *sess = [Session sharedInstance];

    //Add the last actor to the end of the list
    NSMutableDictionary *connections = sess.connections;

    [connections setObject:sess.secondActor forKey:[NSString stringWithFormat:@"%d",kLastFieldtag]];

    BOOL result = [gameManager areAnswersCorrect:sess.connections startingActor:sess.firstActor endingActor:sess.secondActor];
    NSString *display = @"Sorry incorrect. Please recheck your answers.";

    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Result"
                                                    message:display
                                                   delegate:self
                                          cancelButtonTitle:@"Cancel"
                                          otherButtonTitles:@"OK", nil];

    if (result)
    {
        display = @"You are correct! You Won!";

        if (sess.isMutiplayerGame)
        {
            [_gameCenterController endGame];

            [self showGameOverScreen:YES isMultiplayer:YES];
        } 
        else
        {                
            [self showGameOverScreen:YES isMultiplayer:NO];
        }

        dispatch_async(dispatch_get_main_queue(), ^{
            [MBProgressHUD hideHUDForView:self.view animated:YES];

            [alert show];
        });

    } 
    else 
    {
        dispatch_async(dispatch_get_main_queue(), ^{
            [MBProgressHUD hideHUDForView:self.view animated:YES];

            [alert show];
        });
    }
});

Solution

  • This is likely an issue caused by a clash between the MBProgressHUD's animation and the UIAlertView's animation.

    I've never used MBProgressHUD, but looking at the code on GitHub it seems they've already solved your problem. MBProgressHUD has a completionBlock property.

    Code like this should work: (Warning: Untested)

    dispatch_async(dispatch_get_main_queue(), ^{
        [MBProgressHUD HUDForView:self.view].completionBlock = ^{
            [alert show];
        };
        [MBProgressHUD hideHUDForView:self.view animated:YES];
    });
    

    MBProgressHUD fires its completionBlock after the view has finished its animation, so there should no longer be a conflict.

    As a side note the MBProgressHUD method:

    - (void)showAnimated:(BOOL)animated 
     whileExecutingBlock:(dispatch_block_t)block 
                 onQueue:(dispatch_queue_t)queue
         completionBlock:(MBProgressHUDCompletionBlock)completion;
    

    seems like it would be a better fit for your code.