iOS 6 UIWebView状态恢复如何工作?

时间:2013-01-29 16:52:26

标签: ios6 uiwebview restore state-restoration

根据docs

  

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

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

2 个答案:

答案 0 :(得分:12)

文档是正确的,但非常不完整。这是正在发生的事情。如果Web视图参与状态恢复(我假设您知道这意味着什么 - 一切都必须有restorationIdentifier,等等),并且如果Web视图有请求(不是HTML字符串)用户离开应用程序后,Web视图将自动返回到生命,其中包含与其request属性相同的请求,并且其后退和前进列表保持不变。因此,您可以使用状态恢复机制来恢复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状态保存和恢复功能保存并恢复了状态。

答案 1 :(得分:5)

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

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

如果您想了解我的方法示例或您自己的webview的更多功能,请查看我的SVWebViewController的开源分支here.