6

I need to block the interface until the MBProgressHUD operation is done. I did refer this thread,

Block interface until operation is done

According to it, we should disable each individual item which wont work for me. My case is I need to disable user from clicking back button. I did try HUD.userInteractionEnabled = YES which disable every controller except the back button. Is there any way of blocking user from popping out from that controller?

Regards,
Dilshan

Community
  • 1
  • 1
Dilshan
  • 3,231
  • 4
  • 39
  • 50

5 Answers5

12

if u dont find a proper way to do that, you can ignore the whole user interaction by

[[UIApplication sharedApplication] beginIgnoringInteractionEvents];

.U can stop this by

[[UIApplication sharedApplication] endIgnoringInteractionEvents];
sujith1406
  • 2,822
  • 6
  • 40
  • 60
11

You can add the MBProgressHUD to the navigation controller's view so that it also prevents interaction with the back button:

[MBProgressHUD showHUDAddedTo:self.navigationController.view animated:YES];
ToddH
  • 2,801
  • 2
  • 28
  • 28
4

If you want a particular control to make enable when HUD is displaying , you can simply add the line [self.view bringSubviewToFront:yourControl]; in your showHUD method as

-(void) showHUD:(UIView *)view
{

    if (self.HUDdisplayed == NO)
    {
        self.HUDdisplayed = YES;
        HUD = [[MBProgressHUD showHUDAddedTo:self.view animated:YES] retain];
    }
//    HUD.delegate = self;
    [self.view bringSubviewToFront:HUD];
     [self.view bringSubviewToFront:yourControl];

}
SchmitzIT
  • 9,227
  • 9
  • 65
  • 92
Ruchita
  • 41
  • 1
0

This is how I add the MBProgressHUD to my view and it blocks all input until it is removed:

MBProgressHUD HUD = [[MBProgressHUD alloc] initWithView:self.view];
HUD.opacity = 0.7f;

[self.view addSubview:HUD];

HUD.delegate = self;
[HUD show:YES];

Note: self is the view controller the HUD is being add to

Atulkumar V. Jain
  • 5,102
  • 9
  • 44
  • 61
Joe
  • 2,987
  • 15
  • 24
0

@sujith1406's answer is correct. However, the methods he mentioned are deprecated from iOS 13. Here is my protocol based solution to implement MBProgressHUD blocking.

import Foundation
import MBProgressHUD

protocol AppLoader {
    func showLoader()
    func hideLoader()
}

extension AppLoader where Self: UIViewController {
    func showLoader() {
        let views: [UIView?] = [self.navigationController?.view, view]
        views.forEach({ $0?.isUserInteractionEnabled = false })
        MBProgressHUD.showAdded(to: self.view, animated: true)
    }
    
    func hideLoader() {
        let views: [UIView?] = [self.navigationController?.view, view]
        views.forEach({ $0?.isUserInteractionEnabled = true })
        MBProgressHUD.hide(for: self.view, animated: true)
    }
}

extension UIViewController: AppLoader {}

how to use it?

func fetchUserInformation() {
   self.showLoader()
   //perform api call. assuming fetchUserData is an api that fetches a particular user data from the server.
   self.fetchUserData(completion: { [weak self] in 
       self?.hideLoader()
   })
}
Ankur Lahiry
  • 2,253
  • 1
  • 15
  • 25