How to open any link from a UIWebView to a new UIWebView? - iphone

I want to make a simple app, where a UIWebView with custom content will have several links to other pages with similar content as well (and a navigation bar on top, with just a back button).
I read the answers to this question, however I'm not sure if I should do that in my application, as the user might be able to go deep enough, and I will be creating new webviews all the time.
What could be the best practice for such a behavior?
Thank you!

I'd recommend listening for:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType;
and always returning YES (so the webView will continue with the requested link) while storing each request in an NSMutableArray to create a stack of the user's browsing history.
That would let you update a back button's text with the previous page's title (shortened of course).
If you just need to have a back button without label, you could have a simple button hooked up to the UIWebView's - (void) goBack; method.

Related

Switch views in Xcode when a link is clicked from a webview?

I have an app with localhtml inside a webview. The localhtml is basically a list with links to various sites. Is there a way to make one of these links direct to a new view inside the app? Creating a button inside the webview is not an option in this case. The idea I had was to set the link to "switchviews" or something then switch views if the link matched. So like this (just for the concept)
If link matches "switchviews" {
Switch view
}
Is the a valid way to do this and can you share the actual code for doing so? Or is there a more effective way?
You can use UIWebViewDelegate an look to the method:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
There look for the NSURLRequest to known which link is going to be loaded or the UIWebViewNavigationType which tells you what kind of action is happening right now.

iphone: How do I know the UIWebView is fully loaded?

Yes, I know UIWebView has didFinishedLoad & didStartLoad delegate.
However, the didFinishedLoad does not mean the full completion. It may be called when one of the items that the UIWebView is finished loading. i.e., UIWebView may call this delegate several times while loading a single page.
So anyway can tell me how to check whether the UIWebView is fully loaded?
Thanks
J
I have poor experience with DOM but after some searching I found that the document.readyState is the great option.
From w3schools:
Definition and Usage
The readyState property returns the (loading) status of the current document.
This property returns one of four values:
uninitialized - Has not started loading yet
loading - Is loading
interactive - Has loaded enough and the user can interact with it
complete - Fully loaded
So I'm using this to know when UIWebView has loaded the document:
- (void)readyState:(NSString *)str
{ NSLog(#"str:%#",str);
if ([str isEqualToString:#"complete"]||[str isEqualToString:#"interactive"]) {
NSLog(#"IT HAS BEEN DONE");
[pageLoadingActivityIndicator stopAnimating];
}
}
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
//other code...
[self readyState:[browserWebView stringByEvaluatingJavaScriptFromString:#"document.readyState"]];
}
http://www.codingventures.com/2008/12/using-uiwebview-to-render-svg-files/
on Javascript communicating back with Objective-C code
Maybe use document location hash.
And add in the webview html body:
<body onload="document.location.hash='myapp:myobject:myfunction';">
I know its a little bit hacky but works. And it can be used in ajax based contents, because its up to you when you want to call your ready method. Or it can be used as a complete communication scheme.
What you can do is, display a network indicator on the view which is visible in the status bar. When your page is being loaded the indicator will continue rotating until and unless the page is completly loaded. When the page completely loads, the indicator will stop rotating and will be invisible.
Just have a look at this example : Network indicator

A Label in View with UIWebView

I have a View, i would like to put a test ( a UILabel) witch when clicking it, it open me a web View with an URL ( WWW.mySite.com).
How i can do this please ?
thanks for your answers
Use a button, put the text into the button, hook up the actions from the button pressedUpInside to a function which will call the UIWebView's - (void)loadRequest:(NSURLRequest *)request with your URL.
Look up Apple documentation on UIWebView and use a UIButton connected to an IBAction. Always turn to the documentation when these kinds of questions come up. It is really through and usually pretty well done.

UIWebView: webViewDidStartLoad/webViewDidFinishLoad delegate methods not called when loading certain URLs

I have basic web browser implemented using a UIWebView. I've noticed that for some pages, none of the UIWebViewDelegate methods are called.
An example page in which this happens is: http://www.youtube.com/user/google. Here are the steps to reproduce the issue (make sure you insert NSLog calls in your controller's UIWebViewDelegate methods):
Load the above youtube URL into the UIWebView
[notice that here, the UIWebViewDelegate methods do get called when the page loads]
Touch the "Uploads" category on the page
Touch any video in that category
[issue: notice that a new page is loaded, but none of the UIWebView delegates are called]
I know that this is not an issue of UIWebView's delegate not being set properly, since the delegate methods do get invoked when loading other links (e.g. if you try clicking on a link that takes you outside of youtube, you'll notice the delegate methods getting called).
My gut feeling initially was that it might be because the page is loaded using AJAX, which may not invoke the delegate method. But then when I checked the iPhone's Safari, it did not exhibit this problem, so it must be something on my side.
I've also noticed that Three20's TTWebController has the exact same issue as I'm having.
But the problem that arises from this issue is that without the delegate methods called, I'm unable to update the UI to enable/disable the back and forward browsing buttons when new requests are loaded.
And idea why this is happening or how can I work around it to update the UI when a new request is made?
This isn't an iOS bug - the page isn't actually reloading. The UIWebView delegates are triggered following new page requests, but that page doesn't do that.
Look very carefully at what happens in desktop Safari when you click the video link on that page as you describe. Make sure you pay attention to the address bar. The address will change, but critically the page will not reload.
This is all handled by JavaScript, not by reloading the page. Simply put, the page never reloads, so there's no reason for the UIWebView delegates to be called.
If you don't believe me, to conclusively prove this try repeating the steps you describe with JavaScript disabled. You'll notice the page behaves completely differently.
this is not good solution but im using NSTimer for updating status of buttons:
- (BOOL)webView:(UIWebView *)_webview shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
if (!_timer && [request.URL.absoluteString rangeOfString:#"youtube.com"].length != 0) {
_timer = [NSTimer scheduledTimerWithTimeInterval:0.5
target:self
selector:#selector(checkNavigationStatus)
userInfo:nil
repeats:YES];
}
return YES;
}
//....
//....
//....
- (void)checkNavigationStatus
{
// Check if we can go forward or back
backButton.enabled = self.webView.canGoBack;
forwardButton.enabled = self.webView.canGoForward;
}
Looks like this got fixed in iOS 4.2. It works in iOS 4.2.

UIWebView finished loading Event

Is it possible to start an event when an UIWebView (Iphone) has finished loading the URL.
How can I find out, the current URL of the UIWebView?
Yes, that's possible. Use the UIWebViewDelegate protocol and implement the following method in your delegate:
- (void)webViewDidFinishLoad:(UIWebView *)webView
If you want the URL, you can get the last request using the property request:
webView.request.URL
None of the found solutions worked for me.
Then I found this example which at least works much better than any other solution I found on Google/StackOverflow.
uiwebview-load-completion-tracker
Very simple method:
Step 1: Set delegate UIWebViewDelegate in header file.
Step 2: Add following webViewDidFinishLoad method to get current URL of webview
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
NSLog(#"Current URL = %#",webView.request.URL);
//-- Add further custom actions if needed
}
Pascal's answer for the "getting the URL" part is fine.
However!
From UIWebViewDelegate's documentation, from Apple:
"webViewDidFinishLoad: Sent after a web view finishes loading a frame."
Frame != Page.
webViewDidFinishLoad is called when the page is "done loading". It can also be called many times before then. Page loads from Amazon.com can generate a dozen calls to webViewDidFinishLoad.
If you control the page source, then you can make a load test for it, and it will work, for that case. If you only care about getting called "after the page is done loading", then webViewDidFinishLoad is adequate.
For arbitrary pages, with arbitrary JavaScript, loading ad banners in perpetuity, or autoscrolling banners, or implementing a video game, the very idea of a page being "done loading" is wrongheaded.