Search code examples
iphoneobjective-cmbprogresshud

Can't show MBProgressHUD


In here said that using MBProgressHUD is easy. But I can't make it.

Here my code:

- (IBAction)save{
    HUD = [[MBProgressHUD alloc] initWithView:self.navigationController.view];
    [self.navigationController.view addSubview:HUD];
    HUD.delegate = self;
    [HUD show:YES];

    NSString *title = [page stringByEvaluatingJavaScriptFromString:@"document.title"];
    SavePageAs *savePage = [[SavePageAs alloc] initWithUrl:self.site directory:title];
    [savePage save];
    [HUD hide:YES];
}

The progress indicator is not showing during savePage save method run, but shows after the page completely saved (the indicator is shown for less than 1 second).

I also tried this way:

- (IBAction)save {

    HUD = [[MBProgressHUD alloc] initWithView:self.navigationController.view];
   [self.navigationController.view addSubview:HUD];

   HUD.delegate = self;
   HUD.labelText = @"Saving...";

   [HUD showWhileExecuting:@selector(performFetchOnMainThread) onTarget:self withObject:nil animated:YES];
}

- (void) savingPage{
    NSString *title = [page stringByEvaluatingJavaScriptFromString:@"document.title"];
    SavePageAs *savePage = [[SavePageAs alloc] initWithUrl:self.site directory:title];
    [savePage save];
}

-(void) performFetchOnMainThread    {
    [self performSelectorOnMainThread:@selector(savingPage) withObject:nil waitUntilDone:YES];
}

But still no luck. Anyone let me know where I'm lack here?

P.S: savePage save is saving all website contents to local directory. I wish once the saving is complete the progressHUD disappear.

Thanks


Solution

  • Try allocation of HUD on the viewWillAppear: instead of -(IBAction)save because sometimes allocation takes up the whole time and by the time it allocates whole task is finished.

    Copy Following links to viewWillAppear: and remove them from -(IBAction)save

     HUD = [[MBProgressHUD alloc] initWithView:self.navigationController.view];
     [self.navigationController.view addSubview:HUD];
    
     HUD.delegate = self;
     HUD.labelText = @"Saving...";
    

    EDIT: Keep allocations on viewWillAppear: and change code as shown below:

    - (IBAction)save {
        [NSThread detachNewThreadSelector:@selector(showHUD) withObject:nil];
        [self performSelectorOnMainThread:@selector(savingPage) withObject:nil waitUntilDone:YES];
    }
    
    - (void) savingPage{
        NSString *title = [page stringByEvaluatingJavaScriptFromString:@"document.title"];
        SavePageAs *savePage = [[SavePageAs alloc] initWithUrl:self.site directory:title];
        [savePage save];
        [HUD hide:YES];
    }
    
    -(void)showHUD {
        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
       [HUD show:YES];
       [pool release];
    }
    

    What this will do is create a separate thread to display HUD as main thread is being engaged by savingPage method.

    If this too doesn't work, then just change waitUntilDone:YES to waitUntilDone:NO

    Note: As per Apple documentation

    Important If you use Automatic Reference Counting (ARC), you cannot use autorelease pools directly. Instead, you use @autoreleasepool blocks instead. For example, in place of:

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init;
    // Code benefitting from a local autorelease pool.
    [pool release];
    

    you would write:

    @autoreleasepool {
        // Code benefitting from a local autorelease pool.
    }
    

    @autoreleasepool blocks are more efficient than using an instance of NSAutoreleasePool directly; you can also use them even if you do not use ARC.

    Hope this helps.