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 = @"Retri开发者_JAVA百科eving 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];
}
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
}
}
You can try testing to see if the splashView has finished and use performSelector:afterDelay:
to check back later.
My idea is to create a method like this
-(void)dismissWhenReady {
if ( splashView is finished) {
[self.navigationController dismissModalViewControllerAnimated:YES];
} else
[self performSelector:@selector(dismissWhenReady) afterDelay:1.0];
}
}
viewDidLoad
fires too early (before it is displayed), you will want to use -(void)viewDidAppear:(BOOL)animated
to present your modal view instead along with a flag to know if it is the first load. If it still does not display long enough add a delay for the desired amount of time.
精彩评论