为什么iOS7中的UIWebView canGoBack = NO?

时间:2013-09-22 20:21:03

标签: ios objective-c uiwebview ios7 mobile-website

我正在将这个网站嵌入到我的应用中:

NSString *url = [NSString stringWithFormat:@"https://mobile.twitter.com/search?q=%@", @"@test OR #test"];
url = [url stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
[self.twitterWebView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:url]]];

self.twitterWebView.scalesPageToFit = YES;

我有2个按钮可以在这个网站上前后移动。我在打电话

[self.twitterWebView goBack];
[self.twitterWebView goForward];因此。{/ p>

这适用于iOS 6,但在iOS 7上,我的网页视图的canGoBack和canGoForward属性为NO,因此我的后退和前进按钮不起作用。

作为旁注,当第一次安装应用程序,并且第一次加载页面时,我的按钮会起作用。但是当我再次运行我的应用程序时,当我点击网站上的链接时,我的网页视图的canGoBack属性开始返回NO。

我该如何解决这个问题?

编辑:我上传了一个演示我问题的迷你测试应用。您可以从here下载。请在iOS 7模拟器上运行该应用程序,看到后退按钮正在处理应用程序的首次安装。然后退出,再次运行应用程序,你会发现它将停止工作。

顺便问一下,这个问题似乎与推特移动网站有关。您可以尝试其他网站地址并查看。

4 个答案:

答案 0 :(得分:18)

这似乎与HTML5's "Application Cache" functionality有关。首次启动时,网站不会被缓存,UIWebView会正确检测它是否可以前进或后退。一旦填充了缓存,新的UIWebView实例就会决定,即使URL发生变化(可以在UIWebViewDelegate的{​​{3}}中观察到),也无法前进或后退了。 canGoForwardcanGoBack将返回NOgoForwardgoBack将不会执行任何操作。只要此特定站点的HTML5缓存存在,这将在应用程序重新启动时持续存在。

也许此问题仅限于通过JavaScript修改网址webView:shouldStartLoadWithRequest:navigationType:的网络应用。 是的,UIWebView在这种情况下的行为DID在iOS 6和iOS 7之间发生了变化。

我还没有找到解决方案,我们可能不得不等待Apple在iOS 7.1左右修复此问题。

修改

其他人也有这个问题:

  

如果您正在使用应用程序缓存并进行管理   通过哈希或其他技术陈述,历史对象不会   保留您的导航历史记录,因此history.back()永远不会有效   和history.length永远保持在1。

(来自Fragment identifier after the hashmark

修改2

Safari 7.0(9537.71,OS X 10.9 Mavericks中的默认值)中也存在此问题。但是,最近的http://www.mobilexweb.com/blog/safari-ios7-html5-problems-apis-review(r158339)似乎正常工作。在将修复程序发布到iOS和OS X版本之前,这很可能只是时间问题。

编辑3

iOS 7.1和OS X 10.9.2中仍存在此问题。

编辑4

OS X中的iOS 8和Safari 7.1(9537.85.10.17.1)修复了此错误!

相关:

答案 1 :(得分:4)

我在iOS 7中也遇到过这个问题。对我来说有用的是将“canGoBack”代码和“canGoForward”代码移动到shouldStartLoadWithRequest,如下所示。之前,我在webViewDidFinishLoad中使用过,它适用于iOS 6,但不适用于iOS 7.

 - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request
 navigationType:(UIWebViewNavigationType)navigationType
 {
    if ([webView canGoBack])
    {
        [browserBackItem setEnabled:YES];
    }
    else
    {
        [browserBackItem setEnabled:NO];
    }
    if ([webView canGoForward])
    {
        [browserForwardItem setEnabled:YES];
    }
    else
    {
        [browserForwardItem setEnabled:NO];
    }
    return YES;
}

答案 2 :(得分:3)

我有同样的问题。我能够通过以下更改解决它。

实施了一个新方法updateButtons

- (void)updateButtons:(UIWebView*)theWebView {
    if ([theWebView canGoBack])
    {
        self.backButton.enabled = YES;
    }
    else
    {
        self.backButton.enabled = NO;
    }
    if ([theWebView canGoForward])
    {
        self.forwardButton.enabled = YES;
    }
    else
    {
        self.forwardButton.enabled = NO;
    }
     }

添加在 shouldStartLoadWithRequest,webViewDidFinishLoad,didFailLoadWithError 事件中调用上述方法。

现在棘手的部分来了。进行上述更改后,后退和前进按钮按预期工作,但在一个场景中除外。当我们通过按回按钮返回第一页时,它不会被禁用。因为当按下后退/前进按钮加载页面时,它不会触发上述任何事件。它只是从缓存加载。

我尝试了很多方法,但只有一种解决了我的问题。

在WebHistoryItemChangedNotification上添加了一个观察者。

   [[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(webViewHistoryDidChange:)
                                             name:@"WebHistoryItemChangedNotification"
                                           object:nil];

在webViewHistoryDidChange中调用相同的updatebuttons方法。

- (void)webViewHistoryDidChange
{
     [self updateButtons:self.webView];
}

答案 3 :(得分:-1)

将属性更改为" strong"参考,我的问题消失了。

之前:

 @property (nonatomic, weak) IBOutlet UIWebView *webView;

将属性更改为" strong":

 @property (nonatomic, strong) IBOutlet UIWebView *webView;