6

ドキュメントによると:

iOS 6以降では、このビューのrestorementIdentifierプロパティに値を割り当てると、URL履歴、各ページのスケーリングとスクロールの位置、および現在表示されているページに関する情報が保持されます。復元中に、ビューはこれらの値を復元して、Webコンテンツが以前と同じように表示されるようにします。

私はそれをすべてやっていますが、何も起きていません。また、ユーザーが以前に表示していたURLを手動で保存して復元しても、スクロール位置は復元されません。ドキュメントは間違っていますか?

4

2 に答える 2

12

ドキュメントは正しいですが、非常に不完全です。これが何が起こっているのかです。Webビューが状態の復元に参加している場合(これが何を意味するかを知っていると思います-すべてにrestorationIdentifier、などが必要です)、およびユーザーがアプリを離れたときにWebビューにリクエスト(HTML文字列ではない)があった場合、Webビューは、プロパティと同じリクエストを含み、requestBackリストとForwardリストをそのままにして、自動的に元の状態に戻ります。したがって、状態復元メカニズムを使用してWebビューの状態を復元できますが、少し余分なダンスを実行する必要がありますこのダンスは非常に好奇心が強く、あいまいなので、最初は、ドキュメントの主張にもかかわらず、Webビューの状態を実際に保存および復元することはできないという印象を受けました。

ここには2つの秘密があります。それらを知ったら、Webビューの状態の復元を理解できます。

  • 復元されたWebビューは、その要求を自動的にロードしません。それはあなたのコード次第です。

  • 復元されたWebビューが要求をロードした後、[戻る]リストの最初の項目は、ユーザーが残した状態(スクロールとズーム)の同じページになります。

これを知っていると、Webビューの状態を復元するための戦略を簡単に考案できます。最初に、状態を復元していることを検出し、そのことを示すフラグを立てます。

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

これで、状態を復元していること、およびWebビューに魔法のようにリクエストが含まれていることを(おそらくでviewDidAppear:)検出し、そのリクエストをロードできます。

if (self->_didDecode && wv.request)
    [wv loadRequest:wv.request];

トリッキーな部分です。ビューが読み込まれた後、すぐに「戻ります」。これには、実際には、ユーザーの以前のスクロール位置を復元する効果があります(そして、バックスタックの一番上から余分なエントリを削除する効果があります)。次に、フラグを下げて、他のときにこの余分な動きをしないようにします。

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

UIWebViewは、ユーザーが以前にアプリを離れたときの状態になりました。組み込みのiOS6状態保存および復元機能を使用して、状態を保存および復元しました。

于 2013-01-29T16:54:21.647 に答える
5

Mattの回答を試しましたが、うまく機能しますが、履歴スタックに「転送」ページがある場合、それらはWebビューオブジェクト内の復元されたリクエストに置き換えられます。

より良いアプローチは、代わりにwebviewオブジェクトで'reload'メソッドを呼び出すことです。これにより、ズームとコンテンツスクロールのオフセットだけでなく、両方向の履歴が復元されます。

私のアプローチの例や、独自のWebビューの機能が必要な場合は、SVWebViewControllerのオープンソースフォークをここで確認してください。

于 2013-06-26T17:34:45.640 に答える