Search code examples
objective-csyntaxforeachlanguage-features

objective-c modalViewController too quick


    I am having an issue dismissing a modal view controller on a certain edge case. I display the modal view when I am retrieving a PDF to display in a UIWebView. When the file I am retrieving is very small the modal view will try to dismiss too soon. I present the modal view in the view controller that contains the UIWebView. I dismiss it in the UIWebView's didFinishLoad delegate method.

    I am fine with not animating the initial presentation of the modal view... but is that any more safe than what I was doing? does this still have potential to fail, and if so how would you change it? I have been looking through the docs and nothing I have read so far adresses this situation.

//
// This will download the file if not @ specific path, otherwise use local file.
// _myFileManager is a helper class and _myFileRecord is the backing data model
//
-(id)initWithNib... fileRecord:(MYFileRecord *)_myFileRecord
{
    [_myFileManager cacheFileAsync:_myFileRecord delegate:self];
}

- (void)viewDidLoad 
{
    // doesn't seem to work, NO for animated does seem to work
    [self.navigationController presentModalViewController:_splashController 
                                                 animated:YES];        
    _splashController.messageLabel.text = @"Retrieving File...";
}

- (void)recordSaved:(MyFileRecord *)myFileRecord fileName:(NSString *)fileName
{
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL fileURLWithPath:fileName]];
    [_webView loadRequest:request];
}

- (void)webViewDidStartLoad:(UIWebView *)webView {
    _splashController.messageLabel.text = @"Opening File...";
}

//
// This fails when a small file is already cached to disk and the time
// for the webView to finishLoad is faster than the splashView can present itself
//
- (void)webViewDidFinishLoad:(UIWebView *)webView {
    [self.navigationController dismissModalViewControllerAnimated:YES];
}

Solution

  • Try implementing the viewDidAppear in your SplashController, to catch when the view has finished animating, and set a flag. Then you can control if the SplashController's view has finished loading using this flag, and wait for it if it is not finished yet?

    E.g.

    -(void)viewDidAppear {
      if (shouldDismiss) {
        [self dismissViewControllerAnimated:YES];
      }
      readyToDismiss = YES;
    }
    

    And in your main VC:

    -(void)webViewDidFinishLoading:(UIWebView*)webViewv
    {
      if (_splashController.readyToDismiss) {
        [_splashController dismissViewControllerAnimated:YES];
      } else {
        _splashController.shouldDismiss = YES; // will dismiss in viewDidAppear
      }
    }