Clear UIWebView content upon dismissal of modal view (iPhone OS 3.0) - memory

I currently have a UIWebView that is displayed within a modal view. It is basically a detail view that provides a view of a page when the user clicks a link. When the view is dismissed and then brought up again (when the user clicks another link), the previously-loaded content is still visible and the new content loads "on top" of the last content. This makes sense because the instance of the UIWebView persists between sessions and is only released when the memory is needed.
However, I would like to completely clear the UIWebView when the modal view is dismissed so that 1) content is cleared and 2) memory is freed. Thus far my research and attempts have not found an answer. These links haven't worked for me:
is it possible to free memory of UIWebView?
Reused UIWebView showing previous loaded content for a brief second on iPhone
I've tried [[NSURLCache sharedURLCache] removeAllCachedResponses]; and setting the webView to nil and manually releasing the webView upon modal-view-dismiss to no avail. Any thoughts from the wizened masses?

Sometimes loadHTMLString is too slow. You also can use:
[webView stringByEvaluatingJavaScriptFromString:#"document.body.innerHTML = \"\";"];
I'm not sure if that will free up much memory though...

Releasing the web view is probably the best approach. If a view is in a view hierarchy (has a superview) you must call removeFromSuperview to get the superview to release the view.
You could also load an html string for an empty document:
[webView loadHTMLString:#"<html><head></head><body></body></html>" baseURL:nil];

It seems under some circumstances the methods suggested by drawnonward and rob may not work (possibly something to do with CSS on the page that's being cleared), however this did work :
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:#"about:blank"]]];

evaluating javascript is usually quicker than loading a new request.
[webview stringByEvaluatingJavaScriptFromString:#"document.open();document.close();"];

In my case I needed to clear the web view from its contents instantaneously and be able to start loading something else right away. Neither loading an empty document HTML string nor clearing the page with JavaScript resulted in desired effect. Instead I used:
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:#"about:blank"]]];
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:#"http://stackoverflow.com"]]];
And this cleared the view to the default background and initiated next page's loading as expected.
I hope this helps someone else as well.

i prefer to the following:
[m_webView stringByEvaluatingJavaScriptFromString:#"location.replace('about:blank')"]

Related

iOS how to remove existing UIWebView and reinitialise it

I have a UIWebView which load a page when the user navigates he can go to 7 levels I mean he can go to 7 different pages with different URL.
Now I want to go back to the first page directly instead of going back one by one.
I couldn't find any API in UIWebView to do this so I thought to loading the first page url again but UIWebView's cangoback will return true.
So I thought I will reinitialise the webview and load the URL
self.webview=[self.webview init];
as expect it loads the new url and UIWebView's cangoback returns false which is good.
but the problem is when I try to scroll the page down I can see the previous page behind it as background of scrollview.
Any ideas on how to fix the issue
You're leaving the old web view alive, but just calling it's init routine (which you shouldn't do more than once). Instead, call:
self.webview = [[UIWebView alloc] init];
That will give you a whole new web page like you originally started with, and will invoke ARC to dispose of the old one.

UIWebView Content Offset

I want to show a google.maps url into a UIWebView in my app but the page comes up in different point from this that i want. I tried everything of many questions here such as set contentOffset of webview.scrollview or contentInset or scrollsToTop or even with javascript commands but neither of them works.So this is the problem:
and this is the expected result that i would like to have:
I want my webpage to come up on top and not in the middle.
url: url
This has nothing to do with content offsets etc. - it is the page itself which scrolls down right after it finished loading. When loading the URL in Mobile Safari, you will get the exact same behaviour and can even observe the scrolling animation.
Unfortunately, there is nothing you can do to prevent it, except extracting the scroll code from the html the server delivers before loading it in the webview. This would be tedious and you shouldn't do it anyway, since this will likely break your app once changes are made by google to the inner workings of that page.
The only solution I can think of right now is to scroll the page back to top programmatically after it has scrolled down. I've tried it with the url you provided and it acutally works. To do this, implement webViewDidFinishLoad: in your webview delegate like so:
-(void)webViewDidFinishLoad:(UIWebView *)webView {
NSTimer *scrollTimer = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:#selector(scrollBackToTop) userInfo:nil repeats:NO]; // Better make the timer an ivar
}
and implement a method like:
-(void)scrollBackToTop {
NSString* javascript = [NSString stringWithFormat:#"window.scrollTo(0, 0);"];
[theWebView stringByEvaluatingJavaScriptFromString:javascript];
}
This means of course that your webview will first scroll down visibly only to jump back to top, which is rather ugly. So you may want to hide the webview behind an opaque view containing an activity indicator or the like until the webview has loaded and finished all of the scrolling action...
Be aware though that, while less likely and less lethally, this may break as well. When I tried my solution, a 2 second delay was sufficient. If google slows down the animation in the future though, 2 seconds might not be enough and your scrollBackToTop method fires early. Since the java script will not cancel the scroll in progress, it won't scroll back to top at all.
Edit:
Maybe I have something better for you...
Do the following in your webViewDidFinishLoad: method:
NSString* javascript = [NSString stringWithFormat:#"document.getElementById('panel').style.position='fixed'; document.getElementById('panel').style.top='50px';"];
[webView stringByEvaluatingJavaScriptFromString:javascript];
This will completely suppress the scrolling animation. But it comes at a cost: If the user scrolls the webview manually now, the form fields remain fixed in position, while the rest of the page is scrolling normally.
So you need to undo the hack, by doing this:
NSString* javascript = [NSString stringWithFormat:#"document.getElementById('panel').style.position='absolute'; document.getElementById('panel').style.top='0px';"];
[theWebView stringByEvaluatingJavaScriptFromString:javascript];
You need to execute the second step with a delay again, after the scroll script has finished, otherwise the page will do the full scroll. For me, a 1.2 second delay did the trick.
You might want to prevent the user from scrolling during those 1.2 seconds by disabling scrolling on the webviews scrollview until the timer fires.
So there's still room for improvement, but this approach will probably make your app feel more responsive, compared to hiding the webview until it has scrolled back and forth...

Loading a WebView with a specific offset

i'm building an Application that should load an html rendered webpage, it works but, as should be, it loads the view from the top of the page, what if i want it to load from a specific offset ? i've tryed to add the parameters ScrollX and ScrollY in the layout, but it just made the app crash... so how can i achieve such a behavior?
thanks in advance :)
You can set the contentOffset of your WEbView-
And the code will be like this -
[webView setContentOffset:CGPointMake(0,-20) animated:YES];

How can I close UIWebView after submitting form in the view?

I have a UIWebView that displays a webpage including a feedback form. I want to remove this UIWebView after I submit the form in that view.
How can I do that?
You normally achieve this sort of thing by setting a delegate on the web view, to register for interesting callbacks.
Don't forget to nil the delegate before you dispose of the web view or you might experience a crash.
In the delegate for the UIWebView, within
webView:shouldStartLoadWithRequest:navigationType:
search for a the url triggered by the form submission. If it's present, set a flag value.
Then, in your delegate's webViewDidFinishLoad: method, if the flag is set, remove the webView.
Well You Have not made clear of your allocation of your webview or not familiar with your code .I guess you want to return to previous view from the UIWebView , in that case you can simply the push the viewcontroller containing the webview through a UINavigationController and get back to the view on back button or set a flag in webviewDidStartLoad and webViewDidFinishLoad and remove the view when the flag is set in DidFinish Part else please elaborate your problem.

Ensuring memory not leaking in UIWebView

I would like to know if I am using good memory management practise with UIWebView. My app makes extensive use of hundreds of local html files, which the user can get to at the end of a table hierarchy. The user can also swipe left and right for previous and next pages.
In viewDidLoad, I set everything up, such as background colour and gesture recognizers, and I add it to the view:
[self.view addSubview: self.myWebView];
Only in dealloc do I set the UIWebView's delegate to nil, and release it.
In viewWillAppear, I set the UIWebView's delegate to self, while in viewWillDisappear, I set the delegate to nil (as well as ask it to "stopLoading").
Each time I load a new document in, I use loadHTMLString:
[self.myWebView loadHTMLString:fullHTML baseURL:nil];
Is what I'm doing sufficient to keep the memory happy? Is this issue from two years ago still relevant?
Thank you!
What you have written should not leak memory. I don't know if the issue you linked to still happens, but I have not had problems with it in my use of UIWebView.

Resources