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

mat*_*att 6 restore uiwebview ios6 state-restoration

根据文件:

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

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

mat*_*att 12

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

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

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

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

了解这一点,您可以轻松地设计Web视图状态恢复策略.首先要检测我们是否正在恢复状态,然后举起一个标志:

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

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

if (self->_didDecode && wv.request)
    [wv loadRequest:wv.request];
Run Code Online (Sandbox Code Playgroud)

现在是棘手的部分.视图加载后,我们立即"回去".这实际上具有恢复用户之前滚动位置(以及从Back堆栈顶部删除额外条目)的效果.然后我们降低我们的旗帜,这样我们就不会在任何其他时间进行额外的移动:

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

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


Pel*_*let 5

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

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

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