在 UIWebView 中恢复位置

Posted

技术标签:

【中文标题】在 UIWebView 中恢复位置【英文标题】:Restore Position in UIWebView 【发布时间】:2014-11-13 23:42:19 【问题描述】:

我需要将 UIWebView 中的当前位置存储到磁盘,并在以后启动时从磁盘重新加载。

我之前所做的是将window.scrollXwindow.scrollYjavascript 位置一起存储。 这适用于许多情况。

另外我通过获取电流来存储比例:

webView.scrollView.zoomScale

并通过使用 javascript 设置视口初始比例来恢复它。

所有这些都有效,但并不可靠。有没有更好的办法?

我读到了UIWebViewrestorationIdentifier,但我不确定是否可以将其保存到磁盘?

【问题讨论】:

你用java脚本存储值的原因是什么?我不明白。能否请您澄清一下问题,并可能包含一些代码,以便我们可以看到您到底在做什么? 【参考方案1】:

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

查看更多来自Apple Programming Guide 和tutorial 以及示例项目。您可以运行它并将应用程序发送到后台,然后使用Xcode停止运行它,下次打开应用程序时,它会将其状态恢复到应用程序进入后台之前的状态。可以对示例项目进行一个小修复,在viewDidAppear 中,如果self.restoringStateNO,则调用showPage 函数。

【讨论】:

由于某种原因,我不能完全按照描述使用状态保存,因为我不能保证在应用打开后视图是第一个出现的。有没有办法将状态保存到磁盘?我还需要确保网络视图已刷新内容并保持相同的位置(我知道由于站点更改,它不能总是准确的位置,但这没关系) 您可以使用NSUserDefaultcontentOffSetzoomScale保存为NSDictionary,下次打开应用重新加载刷新内容的请求,在webViewDidFinishLoad,你重置了 webView 的 contentOffset 和 webView 的 scrollView zoomScale。 这是我目前所做的。但有时它会造成错误的位置并且设置缩放比例并不可靠 什么不可靠?缩放比例不起作用?我刚刚做了一个测试,它对我有用。【参考方案2】:

明确一点,UIWebView状态恢复(与正常状态恢复类似)的步骤如下:

    在您的应用委托application: shouldRestoreApplicationStateapplication: shouldSaveApplicationState 中返回 true。 呈现的视图控制器 - 设置其恢复 ID - 您可以在情节提要的身份检查器中进行。 ID 可以是任何唯一的字符串。如果您有容器 VC(导航等),则需要为其设置恢复 ID。 在情节提要中为 UIWebView 设置恢复 ID 覆盖applicationFinishedRestoringState 并重新加载webView

我使用了这些步骤,似乎一切正常。但是,在阅读了您的 cmets 之后,我发现您在缩放页面时遇到了问题。问题是 UIWebView 恢复中的一个错误(我认为),它与重新加载机制有关。这就是为什么我建议以下 hack:

import UIKit

class ViewController: UIViewController, UIWebViewDelegate 

    @IBOutlet var webView: UIWebView!
    override func viewDidLoad() 
        super.viewDidLoad()
        webView.delegate = self
        webView.scrollView.restorationIdentifier = "webViewScrollView"
    

    var restoring = false
    override func viewDidAppear(animated: Bool) 
        if !restoring 
            webView.loadRequest(NSURLRequest(URL: NSURL(string: "http://google.com")!))
        

    
    override func didReceiveMemoryWarning() 
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    

    var restoredScrollOffset: CGPoint = CGPoint.zeroPoint
    override func applicationFinishedRestoringState() 
        restoring = true
        restoredScrollOffset = webView.scrollView.contentOffset
        webView.reload()
    

    func webViewDidFinishLoad(webView: UIWebView) 
        if restoring 
            restoring = false
            if webView.scrollView.contentOffset != restoredScrollOffset 
                println("bug - sometimes it may happen")
            
            webView.scrollView.contentOffset = restoredScrollOffset
        
   

因为它是一个 hack,我们不能确定它会完美无瑕 :)

请注意,我在 webview 中设置了滚动视图的恢复标识符,这样我就不必实现 VC 编码功能 - 可以通过 VC 编码/解码覆盖仅编码滚动视图偏移量。

我只设置滚动视图的偏移量;如果缩放比例有问题(我在我尝试过的任何网页中都没有找到),你可以在我设置滚动视图的内容偏移的同一位置设置比例

代码在https://github.com/iamdoron/UIWebViewRestoration

【讨论】:

以上是关于在 UIWebView 中恢复位置的主要内容,如果未能解决你的问题,请参考以下文章

是否可以恢复您上次在 UIwebView Xcode 5 中的位置

使用WKWebView替换UIWebView

在 uiwebview 中播放 youtube 视频。如何处理“完成”按钮?

如何清除/禁用 UIWebView 的浏览历史记录

iOS UIWebView 允许所有三方cookie

IOS UIWebView添加Cookie值请求