how can I clear the contents of a UIWebView/WKWebView? - ios

I have a webview that can be cycled through different URLs. When I switch from one to the other I want the old web page to disappear before loading the next one. How can I do this without re allocating the webview?
If I try to [self.webView loadHTMLString:#"" baseURL:nil]; and load my URL in the same function the previous web page still remains:
[self.webView loadHTMLString:#"" baseURL:nil];
[self.webView loadRequest:[NSURLRequest requestWithURL:self.pageURL]];
EDIT: this apparently isn't clear enough for you. the below code doesn't clear the webview, it displays the previous page until the new one is loaded:
- (void) startLoadOfNextURL:(NSURL*)url
{
// clear:
[self.webView loadHTMLString:#"" baseURL:nil]; //DOESNT WORK
// Load real next URL
NSURLRequest* request = [NSURLRequest requestWithURL:url];
[self.webView loadRequest:request];
}

You can write the code below while your controller dismisses.
webView.load(URLRequest(url: URL(string:"about:blank")!))

You can make it load a blank page
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:#"about:blank"]]];

Use JavaScript instead.
webView.evaluateJavaScript("document.body.remove()")

The following code clears the screen and then navigates
Swift
webView.evaluateJavaScript("document.documentElement.remove()") { (_, _) in
self.webView.load(urlRequest)
}

To clear old contents of webview
When you call - loadHTMLString:baseURL: it doesn't block until the load is complete. Once it records your request, it returns and loads in the background.
As a result, you would need to wait for the first load to finish before kicking off a new load request.
With UIWebView you would use UIWebViewDelegate's
- webViewDidFinishLoad:.
With WKWebView you would use WKNavigationDelegate's
- webView:didFinishNavigation:
Another approach if you really wanted to clear the contents without a delegate method would be to use JavaScript (eg https://stackoverflow.com/a/4241420/3352624). Then for UIWebView you could invoke - stringByEvaluatingJavaScriptFromString:. That method will block execution until the JavaScript executes and returns.
For WKWebView, you would need to do something like https://stackoverflow.com/a/30894786/3352624 since its - evaluateJavaScript:completionHandler: doesn't block.
To make old contents "disappear"
If you really just want to make "the old web page to disappear", you could cover the content area of the webview with a blank UIView temporarily. You could hide the contents when you initiate the load and then show the contents using the delegate methods above after the load completes.

Swift
webView.load(URLRequest(url: URL(string: "about:blank")!))
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1, execute: {
//Load request or write code here
})

Related

Can i send data into webview?

i have created webview in my app,
NSString *htmlFile = [[NSBundle mainBundle] pathForResource:#"SimpleCall" ofType:#"html"];
NSString* htmlString = [NSString stringWithContentsOfFile:htmlFile encoding:NSUTF8StringEncoding error:nil];
[webview loadHTMLString:htmlString baseURL: [[NSBundle mainBundle] bundleURL]];
[self.view addSubview:webview];
now i want to send a data to webview when webview starts load.is there any property for uiwebview?
thanks advance.
you must set the delegate UIWebViewDelegate property on your UIWebView, for example:
webView.delegate = self;
where self conforms to UIWebViewDelegate protocol and implement callback method webViewDidStartLoad (check docs) if you really want to do something when web view starts load. Then, you implement the method:
- (void)webViewDidStartLoad:(UIWebView *)webView {
//you can do something in here, but DON'T call any loaders of webView's - loadHTML or reload, cause this will result in a loop
}
But I doubt that will solve your problem - first of all you probably want to do something when web view finishes. Second - can you elaborate more on what you mean by:
send data to web view
DISCLAIMER: as of iOS 8 and higher you should use WKWebView instead.
EDIT: as clarified in comments you want to update dynamically html contents. In WKWebView docs you can read that there is no option to do that (i.e. dynamically insert options from your NSArray to loaded html string). You have to manually update your html string and then reload WKWebView with new, updated html. Reloading whole html just to update one feature is probably not an option here, so better store the webpage loaded on the server and update dynamically (when web page is updated with new options) by calling:
[webView reload];

webView - how to stop reloading

I am developing an app in Xcode but am having trouble with one part.
Basicly on the main app page, there is a small section that contains a web view. Everytime I change to another view controller and back, i see it flicker and reload. Is there a way to prevent it from reloading every time i open the view? instead just reloading every time I open the app.
This is the code:
NSURL *webUrl = [NSURL URLWithString:#"myurl.com"];
NSURLRequest *webrequestUrl = [NSURLRequest requestWithURL:webUrl];
[webView loadRequest:webrequestUrl];
webView.scrollView.scrollEnabled = NO;
webView.scrollView.bounces = NO;
Your webview is reloading every time you go to that screen is probably because you added it to either viewDidAppear: or viewWillAppear.
Add your block of code to the viewDidLoad method so it only gets executed when the view is loaded (aka when it's shown for the first time).
- (void)viewDidLoad:(BOOL)animated {
NSURL *webUrl = [NSURL URLWithString:#"myurl.com"];
NSURLRequest *webrequestUrl = [NSURLRequest requestWithURL:webUrl];
[webView loadRequest:webrequestUrl];
webView.scrollView.scrollEnabled = NO;
webView.scrollView.bounces = NO;
}
Edit: Oh by going to another view and back you meant going back on the navigation stack (or switching the navigation stack). In that case, you can keep a strong reference to your view controller with the webview and reuse it. Though I wouldn't suggest it doing it this was, unless that screen is the most important screen of your application.
Hope you are having your logic in other than the method
- (void)viewDidLoad
move your code to - viewDidLoad
even if your are having trouble then pass the preloaded UIWebView when ever you are navigating.

PreLoad UIWebView on a not yet displayed UIViewController

I have an app where on the very last UIViewController there is a UIWebView... the user navigates through the app and at the very end they can transition (modal) to the final UIViewController with a UIWebView... in it's viewDidLoad I have the UIWebView load the page.
The problem is it takes about 8 seconds to load this page and that annoys users.
How can I load the UIWebView way ahead of time (like when the app is first launched!) if that UIViewController hasn't even been presented yet?
I had your same problem for UIWebView inside a UIPageViewController and I found a better solution.
If you are in FirstViewController and you have your webView in your SecondViewController put the loadHTMLString or loadRequest method in the viewDidLoad of your SecondViewController and call [secondViewController.view layoutSubviews] for start loading in your FirstViewController.
Ex:
FirstViewController
-(void)viewDidLoad{
[super viewDidLoad];
// _secondViewController -> An instance of SecondVieController
[_secondViewController.view layoutSubviews];
}
SecondViewController
-(void)viewDidLoad{
[super viewDidLoad];
NSURL *url =[NSURL URLWithString:#"http://www.google.it"];
NSURLRequest *request =[NSURLRequest requestWithURL:url];
[self.webView loadRequest:request];
}
What u can do is, load the html string
NSString *htmlFile = [[NSBundle mainBundle] pathForResource:self.path ofType:#"htm"];
NSError * error;
NSString* htmlString = [NSString stringWithContentsOfFile:htmlFile encoding:NSUTF8StringEncoding error:&error];
and when u display the webView load this content in your webView
[self.webView loadHTMLString:htmlString baseURL:[[NSBundle mainBundle] bundleURL]];
then your webview need only render your content and doesn't load the data
/// In Swift 2.0
do{
let path = NSBundle.mainBundle().pathForResource("theName", ofType: "html")!
let html = try String(contentsOfFile: path, encoding: NSUTF8StringEncoding)
webView.loadHTMLString(html, baseURL: nil)
}catch{
print("Error is happend")
}
Note: It works the same way for WKWebView
Not sure how much work you want to do for this but I think you could cache/store the data from the URL in something like a NSDictionary, or something similar, using [NSUserDefaults standardUserDefaults] and use that information before actually loading the page.
So, load the first time you use it, after it has been seen then store the data using NSUserDefaults. Next time you go to this page, load from the NSUserDefaults first and call the URL/API in the back ground then update NSUserDefaults with this new data.
If you are requesting or pulling specific information each time, then I don't think this will work. If that is your case, you can probably try loading the data/website in an earlier view controller (probably one that takes the user a while to navigate to) and then send that data to the webview. Something like delegate/protocol or maybe even NSNotificationCenter. Hope this helps.
UIWebView is very tricky object. Simple answer would be: no you can't.
UIWebView won't load a document or an URL if it is not in views hierarchy.
Don't try doing it in different thread/queue either.
What you can do is to add UIWebView to the views hierarchy at the very beginning (as you've mentioned) and then pass it to the last view controller with preloaded data. This may work, but it's not an elegant way.
Side questions is: why does it take 8 secs to load a page? Maybe you can download the content of this page earlier? Is it static or dynamic?

Why does my WebView not load the new content?

I have a method that loads the content in my WebView:
-(void)loadContent:(NSURLRequest *)requestObj{
//Load the request in the UIWebView.
[webView loadRequest:requestObj];
webView.delegate = self;
NSLog(#"LOAD WEBSITE!!!");
}
when I first call it like this:
[self loadContent:requestObj];
it works fine! But when I call it again for a new URL, it does not work.
I have readed that it will help to call the following before loading the new URL:
[webView stringByEvaluatingJavaScriptFromString:#"document.open();document.close()"];
But it doesn't change the result. Does anyone know how to handle this? Please be patient with me, I'm new in the iOS-world.
Ok i find out, my WebView is Null, but why? I call it from the ViewController and it has to be there. Does someone know how to handle this?
UPDATE: It is not Null any more cause i do this:
if(!webView)
{
webView = [[UIWebView alloc]init];
}
But it does not change the content when i do this: [webView loadRequest:requestObj];
try reloading the view like self reload.nameOfTheView
Is your webview created in a nib? If so, it may not be connected.
http://sweng.epfl.ch/tutorials/getting-started-with-ios-developement-xcode-and-objective-c
you can go through the above link and find a step by step procedure
http://www.raywenderlich.com/2712/using-properties-in-objective-c-tutorial
you can download a sample code from the above link.

Loading a webivew inside a webview in iOS

I am facing an issue while loading a UIWebView.I have a webview(1st) where a url is loaded.when that page is loaded,I am creating a small view which has webview (2nd) on top of the first webview,which is loading a second url.Basically I am loading a webview inside a webview.On click of a url in the second webview,the resulting url has to open in safari,outside the app.
IF i am not setting [webview setDelegate:self],then the page is loaded in the small webview as intended but on click,nothing is happening..
However if i set delegae of second UIWebView as self,the url which needs to be loaded in second UIWebView is getting loaded in first url.
Has anyone done this kind of webview loading earlier.
Please help.your help is deeply appreciated
Thanks
In your current class, you should test wich UIWebView delegate is dealing with
First set:
webView.delegate = self;
then in shouldStartLoadWithRequest:
//UIWebView *smallWebView;
//UIWebView *mainWebView;
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
if(webView == smallWebView
{
//Load stuff on safari
}
else
{
//This means that link was pressed in the mainWebView
//Depending on your logic, you will load the smallWebView
}
}

Resources