6

根据文档

在 iOS 6 及更高版本中,如果您为此视图的 restoreIdentifier 属性分配一个值,它会尝试保留其 URL 历史记录、每个页面的缩放和滚动位置以及有关当前正在查看的页面的信息。在恢复过程中,视图会恢复这些值,以便 Web 内容与之前一样显示。

我正在做这一切,但什么都没有发生。即使我手动保存和恢复用户之前查看的 URL,滚动位置也不会恢复。文档是错的吗?

4

2 回答 2

12

文档是正确的,但非常不完整。这是正在发生的事情。如果 Web 视图参与状态恢复(我假设您知道这意味着什么 - 一切都必须有restorationIdentifier,等等),并且当用户离开应用程序时,如果 Web 视图有请求(不是 HTML 字符串) ,Web 视图将自动恢复,包含与其属性相同的请求request,并且其 Back 和 Forward 列表保持不变。因此,您可以使用状态恢复机制来恢复 Web 视图的状态,但您必须执行一些额外的操作。这种舞蹈是如此的好奇和晦涩,以至于最初我的印象是 Web 视图的状态无法真正保存和恢复,尽管文档声称它可以。

这里有两个秘密;一旦你了解了它们,你就会明白 web 视图状态恢复:

  • 恢复的 Web 视图不会自动加载其请求;这取决于你的代码。

  • 在恢复的 Web 视图加载其请求后,其后退列表中的第一项是与用户离开它的状态相同的页面(滚动和缩放)。

了解了这一点,您就可以轻松设计出一种用于恢复 Web 视图状态的策略。第一件事是检测我们正在恢复状态,并提出这样的标志:

-(void)decodeRestorableStateWithCoder:(NSCoder *)coder {
    [super decodeRestorableStateWithCoder:coder];
    self->_didDecode = YES;
}

现在我们可以检测(可能在 中viewDidAppear:)我们正在恢复状态,并且 Web 视图神奇地包含一个请求,并加载该请求:

if (self->_didDecode && wv.request)
    [wv loadRequest:wv.request];

现在是棘手的部分。视图加载后,我们立即“返回”。这实际上具有恢复用户先前滚动位置的效果(以及从 Back 堆栈顶部删除额外条目)。然后我们降低我们的旗帜,这样我们就不会在其他任何时候做出这个额外的动作:

- (void)webViewDidFinishLoad:(UIWebView *)wv {
    if (self->_didDecode && wv.canGoBack)
        [wv goBack];
    self->_didDecode = NO;
}

UIWebView 现在处于用户之前离开应用程序时的状态。我们使用内置的 iOS 6 状态保存和恢复功能保存和恢复了状态。

于 2013-01-29T16:54:21.647 回答
5

我已经尝试过 Matt 的回答并且效果很好,但是如果历史堆栈中有“转发”页面,它们将被 Web 视图对象中恢复的请求所取代。

更好的方法是调用 webview 对象上的 'reload' 方法,这将恢复两个方向的历史记录以及缩放和内容滚动偏移量。

如果您想要我的方法示例或您自己的 webview 的更多功能,请在此处查看我的 SVWebViewController 的开源分支

于 2013-06-26T17:34:45.640 回答