簡體   English   中英

如何在 iPhone 上的 UIWebview 中清除后退列表?

[英]How to clear back forward list in UIWebview on iPhone?

我想訪問/清除后退列表,就好像UIWebView是新的一樣。 是否有任何公共 API 或解決方法可以做到這一點?

我試過:

while ([webview canGoback]) {
    [webview goBack];
}

但這會凍結設備(模擬器也是如此)。

免責聲明
與任何類似的事情一樣,請記住,結果可能無法通過應用程序商店的批准,並且可能根本不適用於 SDK 的未來修訂版。


SDK 中沒有執行此操作的官方方法。 但是,如果您真的想清除UIWebView的后退/前進歷史記錄,則可以通過深入研究私有框架來完成。

一種快速而骯臟的方法(帶有一堆丑陋的編譯器警告)如下:

鑒於myUIWebViewInstance是一個完全正常的UIWebView實例:

id internalWebView=[[myUIWebViewInstance _documentView] webView];       
[internalWebView setMaintainsBackForwardList:NO];
[internalWebView setMaintainsBackForwardList:YES];

框架中還有一個相當誘人的_clearBackForwardCache方法,但是它似乎在被_clearBackForwardCache時並沒有做太多事情。 只是翻轉布爾值對我來說是一種享受。

如果您嘗試“重用”現有的 UIWebView,並禁用返回到它之前所在的任何頁面的功能,您可以:

  1. 加載新請求(用戶不應返回的請求)時,保存新請求的 URL,例如:

    self.curURL = [NSURL urlWithString:@"http://www.bla.com"];
    [webview loadRequest:[NSURLRequest requestWithURL:curURL]];

  2. 我猜你有自己的后退按鈕,所以在你的 webViewDidFinishLoad 委托方法上,添加:

    backbttn.enabled = webView.canGoBack && ![[webView.request URL] isEqual: curURL];

這樣,用戶甚至不會知道 UIWebView 可以返回之前的頁面。

只需重新創建網絡視圖。 它會重置一切,包括歷史。

我使用以下代碼行成功了(只要您可以將這種解決方法稱為“成功”):

[webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"if( window.history.length > 1 ) { window.history.go( -( window.history.length - 1 ) ) }; window.setTimeout( \"window.location.replace( '%@' )\", 300 );", targetLocation]];

其中targetLocation是所需的 URL 作為NSString

它的作用是告訴瀏覽器盡可能向后移動歷史記錄,然后在短暫的超時后加載所需的 URL。

這當然不能解決清除前進歷史的問題(在我的情況下我不需要)。

我認為如果您釋放 uiwebview 對象並重新創建,那么它會清除歷史記錄。 我實際上有一個反向問題。 如果我的 uiwebview 對象在不可見視圖中,它會在低內存事件期間自動釋放。 然后我必須在 viewDidLoad 中重新創建它,但它不會保留從那時起的歷史記錄。

借鑒 Gilbert 的聰明方法:如果修改,它確實適用於重定向(正如 mharper 指出的那樣,它目前無法做到這一點)。

在加載請求之前,保存所需的 URL 並設置一個名為_saveURL的布爾成員變量以指示應保存重定向 URL(稍后您將看到這兩個變量的確切用法):

- (void)my_loadURL:(NSURL *)url
{
    NSURLRequest *request = [NSURLRequest requestWithURL:url]; // create the request
    [_desiredURL release]; // clear up the previous value (assuming -my_loadURL: may be called multiple times)
    _desiredURL = [url retain]; // store the desired URL (will be used later)
    _saveURL = YES; // will also be used later
    [_webView loadRequest:request]; // start loading the request
}

(如果在自動引用計數 (ARC) 環境中編譯,則當然不需要保留和釋放調用。)

現在在-webViewDidFinishLoad:委托回調中,通過測試 web 視圖的當前請求的 URL 是否與所需的 URL 不同來檢查重定向是否已經發生。 如果是這樣,請將重定向 URL 保存在成員變量_firstURL 這也是_saveURL地方。 這是為了避免每次調用此委托方法時都覆蓋_firstURL 此外,按照我們以前的方式啟用或禁用后退和前進按鈕。

- (void)webViewDidFinishLoad:(UIWebView *)webView
{
    // grab the URL currently being loaded
    NSURL *currentURL = [webview.request URL];

    // check whether we are supposed to save the redirect URL and
    // whether redirection has taken place yet
    if (_saveURL && ![currentURL isEqual:_desiredURL]) {
        [_firstURL release];
        _firstURL = [currentURL retain];
    }

    // adjust the enabled-state of the back and forward buttons just like before
    _backButton.enabled = _webView.canGoBack && ![currentURL isEqual:_firstURL];
    _forwardButton.enabled = _webView.canGoForward;
}

(同樣,啟用 ARC 時不需要保留和釋放。)

但是,這種方法有一個主要缺點。 只有當您確定傳入my_loadURL:的 URL 將重定向時,它才有效。 否則, _firstURL變量將在其他時間設置。 因此,如果您無法判斷相應的 URL 是否會重定向,則此方法不適合您的需求。 無論如何,它確實符合我的需求,我希望我也可以幫助其他人。

更新:您可以通過刪除處理 _desiredURL 的所有內容來改進此方法,這意味着不要將所需的 URL 保存在-my_loadURL:-webViewDidFinishLoad:只需說if(_saveURL) 這樣,它將適用於根本不重定向或立即重定向的網站。

我已經嘗試了幾乎所有發布的解決方案,但都沒有取得多大成功。 我的案例是 Childbrowser phonegap 插件,但基於同樣的問題,單個 webview 實例用於在我的應用程序中顯示外部頁面。 當我顯示外部頁面時,webview 會保留顯示的先前頁面的歷史記錄。 我想在顯示新的外部網頁時刪除歷史記錄。

經過一些研究,我在這篇 SO 帖子中找到了一個對我有用的解決方案。

[webView stringByEvaluatingJavaScriptFromString:@"document.body.innerHTML = \"\";"];

在子瀏覽器的情況下,我將它放在方法-(IBAction) onDoneButtonPress:(id)sender ,該方法之前插入了一個空白頁面以開始空白(但啟用了后退按鈕)。

哼! 米爾頓。

我想你可以通過手動加載一些 HTML 來打破歷史......

類似的東西:

[webview loadHTMLString:@"" baseURL:@""];

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM