【问题标题】:objective-c modalViewController too quickObjective-c modalViewController 太快了
【发布时间】:2011-07-14 20:16:28
【问题描述】:

    我在关闭某个边缘情况下的模态视图控制器时遇到问题。当我检索要在 UIWebView 中显示的 PDF 时,我会显示模态视图。当我正在检索的文件非常小时,模式视图将尝试过早关闭。我在包含 UIWebView 的视图控制器中呈现模态视图。我在 UIWebView 的 didFinishLoad 委托方法中将其关闭。

    我可以不为模态视图的初始演示设置动画……但这是否比我所做的更安全?这仍然有可能失败吗?如果有,你将如何改变它?我一直在查看文档,到目前为止我读过的任何内容都没有解决这种情况。

//
// 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];
}

【问题讨论】:

    标签: objective-c syntax foreach language-features


    【解决方案1】:

    尝试在 SplashController 中实现viewDidAppear,以捕捉视图何时完成动画,并设置一个标志。那么你可以使用这个标志来控制SplashController的view是否加载完成,如果还没有加载就等待它呢?

    例如

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

    在你的主要 VC 中:

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

    【讨论】:

    • 这行得通,但是我只使用一个 bool readyToDismiss 并用它替换 shouldDismiss。你觉得这有什么问题吗?
    • 没有 pb,这也应该没问题(而且更简单)!为了便于阅读,我在回答中使用了两个 BOOL,但你是对的,在这种情况下,两种情况(动画在 webview 之前完成,或相反)都只使用一个 BOOL。
    【解决方案2】:

    您可以尝试测试一下 splashView 是否已完成并使用performSelector:afterDelay: 稍后再查看。

    我的想法是创建一个这样的方法

    -(void)dismissWhenReady {
        if ( splashView is finished) {
            [self.navigationController dismissModalViewControllerAnimated:YES];
        } else 
            [self performSelector:@selector(dismissWhenReady) afterDelay:1.0];
        }
    }
    

    【讨论】:

    • 这本质上是轮询,我想避免 +1,因为它可能是一个可行的解决方案。
    【解决方案3】:

    viewDidLoad 触发太早(在显示之前),您将需要使用-(void)viewDidAppear:(BOOL)animated 来显示您的模态视图,并带有一个标志以了解它是否是第一次加载。如果它仍然没有显示足够长的时间,请添加所需时间的延迟。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-06-26
      • 1970-01-01
      • 1970-01-01
      • 2016-03-21
      • 1970-01-01
      • 2010-11-28
      • 2014-02-01
      相关资源
      最近更新 更多