Восстановить позицию в UIWebView

Мне нужно сохранить текущую позицию в UIWebView на диск и перезагрузить ее с диска при более позднем запуске.

Раньше я сохранял window.scrollX и window.scrollY в позиции javascript. Это хорошо работает во многих случаях.

Дополнительно я сохраняю шкалу, получая ток:

webView.scrollView.zoomScale

и восстановите его, установив для него начальный масштаб видовых экранов с помощью javascript.

Все это работает, но ненадежно. Есть способ лучше?

Я читал о restorationIdentifier UIWebView, но не уверен, смогу ли я сохранить его на диск?


person arnoapp    schedule 13.11.2014    source источник
comment
для чего вы сохраняете значение с помощью java-скрипта (причина)? Я не понимаю. Не могли бы вы прояснить вопрос и, возможно, добавить код, чтобы мы могли видеть, что именно вы делаете?   -  person    schedule 23.11.2014


Ответы (2)


В iOS 6 и более поздних версиях, если вы присваиваете значение свойству recoveryIdentifier этого представления, оно пытается сохранить историю URL-адресов, положения масштабирования и прокрутки для каждой страницы, а также информацию о том, какая страница просматривается в данный момент. Во время восстановления представление восстанавливает эти значения, чтобы веб-контент выглядел так же, как и раньше.

См. Больше на Руководство по программированию Apple и руководство вместе с примером проекта. Вы можете запустить его и отправить приложение в фоновый режим, а затем прекратить его запуск с помощью Xcode. В следующий раз, когда вы откроете приложение, оно восстановит свое состояние до состояния до перехода приложения в фоновый режим. В примере проекта может быть небольшое исправление в viewDidAppear, если self.restoringState равно NO, вы вызываете showPage функцию.

person gabbler    schedule 16.11.2014
comment
По какой-то причине я не могу использовать сохранение состояния точно так, как описано, потому что я не могу гарантировать, что представление появится первым после открытия приложения. Есть ли способ сохранить состояние на диск? Мне также нужно убедиться, что веб-представление обновило контент и сохранило ту же позицию (я знаю, что это не всегда может быть точная позиция из-за изменений сайта, но это нормально) - person arnoapp; 16.11.2014
comment
Вы можете использовать NSUserDefault, чтобы сохранить contentOffSet и zoomScale как NSDictionary, в следующий раз, когда вы откроете приложение, вы перезагрузите запрос на обновление содержимого, в webViewDidFinishLoad вы сбросите contentOffset в webView и scrollView zoomScale в webView. - person gabbler; 16.11.2014
comment
Это то, чем я занимаюсь сейчас. Но иногда он делает неправильные позиции и установка масштаба масштабирования ненадежна. - person arnoapp; 16.11.2014
comment
Что ненадежно? Масштаб увеличения не работает? Я только что сделал тест, и он у меня работает. - person gabbler; 16.11.2014

Чтобы было ясно, шаги для восстановления состояния UIWebView (аналогично восстановлению нормального состояния) следующие:

  1. В вашем приложении делегат application: shouldRestoreApplicationState, application: shouldSaveApplicationState возвращает значение true.
  2. Представленный контроллер представления - установите его идентификатор восстановления - вы можете сделать это в инспекторе идентичности раскадровки. ID может быть любой уникальной строкой. Если у вас есть контейнер VC (навигация и т. Д.), Вам необходимо установить для него идентификатор восстановления.
  3. Установите идентификатор восстановления для UIWebView в раскадровке.
  4. Отмените applicationFinishedRestoringState и перезагрузите webView

Я использовал этот шаг, и все вроде работало. Однако после прочтения ваших комментариев я увидел, что у вас проблемы с увеличенными страницами. Проблема заключается в ошибке в восстановлении UIWebView (я думаю), и это связано с механизмом перезагрузки. Вот почему я предлагаю следующий прием:

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
        }
   }

потому что это взлом, мы не можем быть уверены, что он будет безупречным :)

Обратите внимание, что я установил идентификатор восстановления для представления прокрутки в веб-просмотре, чтобы мне не пришлось реализовывать функцию кодирования VC - можно кодировать только смещение прокрутки с помощью переопределений кодирования / декодирования VC.

Я только устанавливаю смещение просмотра прокрутки; если у вас есть проблемы с масштабированием (чего я не нашел ни на одной веб-странице, которую я пробовал), вы можете просто установить масштаб в том же месте, где я установил смещение содержимого для просмотра прокрутки

Код находится в https://github.com/iamdoron/UIWebViewRestoration.

person surui    schedule 21.11.2014