【问题标题】:UIWebView: webViewDidStartLoad/webViewDidFinishLoad delegate methods not called when loading certain URLsUIWebView:加载某些 URL 时未调用 webViewDidStartLoad/webViewDidFinishLoad 委托方法
【发布时间】:2010-12-03 08:20:53
【问题描述】:

我使用UIWebView 实现了基本的网络浏览器。我注意到对于某些页面,没有调用任何 UIWebViewDelegate 方法。

发生这种情况的示例页面是:http://www.youtube.com/user/google。以下是重现问题的步骤(确保在控制器的 UIWebViewDelegate 方法中插入 NSLog 调用):

  1. 将上述 youtube URL 加载到 UIWebView [请注意,在页面加载时,UIWebViewDelegate 方法确实会被调用]
  2. 触摸页面上的“上传”类别
  3. 触摸该类别中的任何视频 [问题:注意加载了一个新页面,但没有调用任何 UIWebView 委托]

我知道这不是 UIWebView 的委托设置不正确的问题,因为在加载其他链接时会调用委托方法(例如,如果您尝试单击将您带到 youtube 之外的链接,你会注意到委托方法被调用)。

我最初的直觉是,这可能是因为页面是使用 AJAX 加载的,它可能不会调用委托方法。但是后来我检查了iPhone的Safari,并没有出现这个问题,所以一定是我这边出了问题。

我还注意到 Three20 的 TTWebController 与我遇到的问题完全相同。

但由此问题引发的问题是,如果没有调用委托方法,我无法更新 UI 以在加载新请求时启用/禁用后退和前进浏览按钮。

知道为什么会发生这种情况,或者我该如何解决它以在发出新请求时更新 UI?

【问题讨论】:

  • 我开始认为这可能是一个 iOS 错误?
  • 我不在我的 Mac ATM 上尝试这个问题,但有趣的是你提到它发生在某个视频页面上。难道是页面保持打开连接以进行流式传输?我建议您尝试使用页面 URL 进行 NSURLRrquest,并查看加载 HTML 数据后连接是否关闭。
  • 嘿,你解决过这个问题吗?我正在玩 m.youtube.com,这是一场噩梦。

标签: iphone uiwebview uiwebviewdelegate


【解决方案1】:

这不是 iOS 错误 - 页面实际上并未重新加载。 UIWebView 委托在新页面请求后触发,但该页面不这样做。

仔细观察当您点击您所描述的页面上的视频链接时,桌面 Safari 会发生什么。确保您注意地址栏。地址会改变,但关键是页面不会重新加载

这一切都由 JavaScript 处理,而不是通过重新加载页面。简单地说,页面永远不会重新加载,因此没有理由调用 UIWebView 委托

如果您不相信我,为了最终证明这一点,请尝试在禁用 JavaScript 的情况下重复您描述的步骤。您会注意到页面的行为完全不同。

【讨论】:

  • 嗯...有趣。感谢您的回答。那么,当 javascript 涉及更改页面时,应该如何挂钩这种事件呢?我需要知道发生了这个特殊的事情,以便我更新后退/前进按钮的可用性。 Safari 似乎可以正确处理它,所以一定有办法做到这一点。
  • 我想你也许可以使用 JavaScript 在它发生时获取回调?您在 Desktop Safari 中看到后退按钮起作用的原因是因为 JavaScript 会写入历史记录,给人的印象是您实际上已经进行了 AJAX 调用(Google 在 GMail 中使用了这种技术)每时每刻)。我猜 Mobile Safari 并没有像桌面那样实现这一点。我不是 JS 专家,所以我不知道从哪里开始。
  • 嗯,我不确定这是否真的发生在这里。我指的是 iPhone 上的移动 Safari,它没有出现这样的问题,使用完全相同的网站。我仍然无法解释。
【解决方案2】:

这不是很好的解决方案,但我使用 NSTimer 来更新按钮的状态:

- (BOOL)webView:(UIWebView *)_webview shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
    if (!_timer && [request.URL.absoluteString rangeOfString:@"youtube.com"].length != 0) {
        _timer = [NSTimer scheduledTimerWithTimeInterval:0.5
                                                  target:self
                                                selector:@selector(checkNavigationStatus)
                                                userInfo:nil
                                                 repeats:YES];
    }

    return YES;
}

//....
//....
//....

- (void)checkNavigationStatus
{
    // Check if we can go forward or back
    backButton.enabled = self.webView.canGoBack;
    forwardButton.enabled = self.webView.canGoForward;
}

【讨论】:

    【解决方案3】:

    看起来这个问题在 iOS 4.2 中得到了修复。它适用于 iOS 4.2。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多