My goal is to allow UIWebView load initial link, but disallow any further navigation.
I saw question:
Disable hyperlinks in UIWebView
So, I wired referenced webView property from interface builder.
I specified that my UIViewController uses UIWebViewDelegate:
#interface LegalViewController : UIViewController<UIWebViewDelegate>
In the code, on viewDidLoad, I do following:
mFirstLoad = TRUE;
webView.delegate = self;
And I have following code:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
if (!mFirstLoad)
return FALSE;
mFirstLoad = FALSE;
return TRUE;
}
shouldStartLoadWithRequest is called both initial call and when I click on the link. However, even if shouldStartLoadWithRequest returns FALSE, UIWebView still proceeds and loads a new page.
I see this problem on iOS Simulator 6.0
How can I fix this behavior?
return NO based on type to exclude links
return !(navigationTpe==UIWebViewNavigationTypeLinkClicked);
Is it possible your boolean is getting reset somehow? What happens if you just return NO for (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType?
Here is the same thing which I wrote in comments:
I think I found the reason for the problem. I am not sure how to properly call it (not a big expert on HTML and Javascript). However the link has following code : "<a href="/something" data-transition="flip"</a> As result, callback is called, but it looks like results of this callback is ignored.
As result most likely solution is here: Remove hyperlinks in uiwebview
Related
Is there a way to have two webview synchronized.
I would like to display on a second screen using Airplay the same WebView but in 16:9.
I managed to create a separate window for the second screen (which is 16:9) and load my local html file but the actions on my iPad screen are not synced with this second screen.
I just have two independent windows.
I really want to use the second screen to display a larger HTML file.
"Synchronized" is underspecified in the OP, but given the most essential representation of a web view's state is it's request, you could try the following: In the controller of the webView that the user is controlling (call it "webViewA"), declare conformance to UIWebViewDelegate:
self.webViewA.delegate = self;
then:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
UIWebView *webViewB = // presuming you have a way to get this pointer
[webViewB loadRequest:request];
}
You can achieve scrolling synchronization (probably the next most essential part of state) by declaring the same controller as conforming to UIScrollViewDelegate, and then:
self.webViewA.scrollView.delegate = self;
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
UIWebView *webViewB = // ...
[webViewB setContentOffset:scrollView.contentOffset animated:YES];
}
I'm facing a problem trying to take screenshots form UIWebViews. I need to take some screenshots of my UIWebView and it works but the screenshot is not correct because they are taken in the event webViewDidFinishLoad, but it calls webViewDidFinishLoad when the UIWebView is not loaded fully, I mean, I take the screenshot in the event webViewDidFinishLoad but the UIWebView is not correctly and fully loaded so it takes a screenshot and it makes right but the screenshot is not totally correct because its the event is triggered (webViewDidFinishLoad) but the UIWebView is not totally loaded. Any ideas?
Thank you very much
A user was having a issue with their use of a activity indicator that apears until a page has loaded but theirs would come back after the main content had loaded the question is here UIWebView not finishing loading? and the answer code is used below. After the code I will go into detail about how this could be used for your situation.
(In the code below the web page truly starts loading on //show UIActivityIndicator and truly finishes loading the main content (not the extra content you are struggling with) on //hide UIActivityIndicator)
//Define the NSStrings "lastURL" & "currentURL" in the .h file.
//Define the int "falsepositive" in the .h file. (You could use booleans if you want)
//Define your UIWebView's delegate (either in the xib file or in your code)
- (void)webViewDidFinishLoad:(UIWebView *)webView {
lastURL = [[NSString alloc] initWithFormat:#"%#", webView.request.mainDocumentURL];
if (falsepositive != 1) {
NSLog(#"Loaded");
//hide UIActivityIndicator
} else {
NSLog(#"Extra content junk (i.e. advertisements) that the page loaded with javascript has finished loading");
//This method may be a good way to prevent ads from loading hehe, but we won't do that
}
}
-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType; {
NSURL *requestURL =[request mainDocumentURL];
currentURL = [[NSString alloc] initWithFormat:#"%#", requestURL]; //not sure if "%#" should be used for an NSURL but it worked...
return YES;
}
- (void)webViewDidStartLoad:(UIWebView *)webView {
if ([currentURL isEqualToString:lastURL]) {
falsepositive = 1;
NSLog(#"The page is loading extra content with javascript or something, ignore this");
} else {
falsepositive = 0;
NSLog(#"Loading");
//show UIActiviyIndicator
}
}
When a page loads in iOS, webviewdidstart and webviewdidfinish are called but not knowing the difference in your main page/html content objective-c calls this again for extra content such as ads or frames. Using this if I were in your situation I would create a BOOL such as pageIsLoading and set it to true in webviewdidstart and then set it to false in webviewdidfinish. After the BOOL is turned off in webviewdidfinish I would end webviewdidfinish by calling a method that will check after a short delay if the BOOL pageIsLoading == YES and if it is, do nothing because more content is loading. If pageIsloading == no then all content must be loaded and now would be a good time to take your snapshot.
Rather than taking screenshot in the event webViewDidFinishLoad you can try to take the screenshot explicitly using UIButton. Let this button be disabled and you can just set this button's enabled property to YES after web view fully loads its content.
On button click to can implement your code to take screenshot.
Edited : Webview's webViewDidFinishLoad method is called when it finishes loading its content. Might be its possible that it may be taking some time to render some images/content on its view.
If possible you can use NSTimer in your webViewDidFinishLoad method to wait for sufficient time(1 min) so that mean while webview can load its content fully.
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:60.0
target: self
selector: #selector(MethodName:)
userInfo: nil
repeats: NO];
In Selector method you can implement your code of taking screenshot.
Hope this will help you...
So I'm writing my first app, and have a quick question about blocking other domains in UIWebView. I would like to restrict navigation to my website, and my partner website only. So, if there happens to be a link on my site that links to Google, I'd like for a popup message to occur and say "You can't go there!" or something. I'm not sure how to go about this. I've never played with UIWebView before and am pretty new to programming in general.
Any help is greately appreciated, thanks!
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
NSString *host = [request.URL host];
if ([host isEqualToString:"oralb.com"] || [host isEqualToString:"other.com"]) {
// Add any of your own domains in the above line
return YES;
}
return NO;
}
You need to make your controller class the delegate of the web view. Then implement this method in the controller:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
In this method you can examine the request to see if its URL is acceptable. If it is, return YES, if not, show your alert and return NO.
To test the domain you can request the host from the URL of the request.
For security reasons, I used to use an anonymizer on mobile safari. However It was a bit annoying. If I searched for something and clicked on a link, then google returns an error message. You can try.. http://proxy2974.my-addr.org/myaddrproxy.php/http/www.google.com.au/ (search for something and click on a link -- it works fine if you test it on desktop browsers.. however it will return http://proxy2974.my-addr.org/myaddrproxy.php/http/url if you try it on iPhone or iPhone simulator)
So I decided to make my own. What I am doing is to get the URL from the text field and pass it through the anonymizer's link like urlString = [NSString stringWithFormat:#"http://proxy2974.my-addr.org/myaddrproxy.php/http/%#", urlString];
However I am still facing the same problem.. When I click on a link on google, it returns an error.. So what I want to do is to get the clicked link, stop loading the page (before it returns an error), then pass it through the anonymizer.. How can I do that? Thanks..
- (BOOL)webView:(UIWebView *) sender shouldStartLoadWithRequest:(NSURLRequest *) request navigationType:(UIWebViewNavigationType) navigationType {
NSLog(#"req: %#",request.URL.absoluteString);
return YES;
}
req: http://proxy2974.my-addr.org/url?sa=t&source=web&cd=1&ved=0CFMQFjAA&url=%2Fmyaddrproxy.php%2Fhttp%2Fwww.perthnow.com.au%2Ffun-games%2Fleft-brain-vs-right-brain%2Fstory-e6frg46u-1111114517613&ei=GXAsUMaUA7H44QTys4HYDA&usg=AFQjCNGB_zOrrEZC0SKx813XGHB1xi_AlA
req: http://proxy2974.my-addr.org/myaddrproxy.php?proxy_url_sjla67z78f8viz4=url&sa=t&source=web&cd=1&ved=0CFMQFjAA&url=%2Fmyaddrproxy.php%2Fhttp%2Fwww.perthnow.com.au%2Ffun-games%2Fleft-brain-vs-right-brain%2Fstory-e6frg46u-1111114517613&ei=GXAsUMaUA7H44QTys4HYDA&usg=AFQjCNGB_zOrrEZC0SKx813XGHB1xi_AlA
req: http://proxy2974.my-addr.org/myaddrproxy.php/http/url
Implement this delegate method to retrieve a clicked link in UIWebView:
- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType
{
if(navigationType == UIWebViewNavigationTypeLinkClicked)
{
NSLog(#"req: %#",request.URL.absoluteString);
}
}
implement
- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType;
in your uiwebview delegate
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
}
}