根据docs:
在iOS 6及更高版本中,如果为此视图的restorationIdentifier属性指定值,它会尝试保留其URL历史记录,每个页面的缩放和滚动位置以及有关当前正在查看哪个页面的信息。在恢复期间,视图会恢复这些值,以便Web内容与之前一样显示。
我正在做所有这些,但一切都没有发生。即使我手动保存并恢复用户之前查看的URL,也不会恢复滚动位置。文档是错的吗?
答案 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.