UIWebView cannot click link - iphone

I am pretty sure that I understand how to catch a click on a UIWebView using the webView:shouldStartLoadWithRequest:navigationType: method, but my webView does not even allow me to click the link. I am using:
UIWebView *webView = [[UIWebView alloc] initWithFrame:CGRectMake(12, top, boundsSize.width - 40.0, 400.0f)];
webView.delegate = self;
webView.backgroundColor = [UIColor clearColor];
webView.opaque = NO;
webView.allowsInlineMediaPlayback = YES;
webView.dataDetectorTypes = UIDataDetectorTypeAll;
// add to subview
I am loading in an HTML string rather than loading a URL:
[webView loadHTMLString:bodyHTML baseURL:nil];
Delegate method:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
NSLog(#"Loaded");
if (navigationType == UIWebViewNavigationTypeLinkClicked) {
NSURL *url = request.URL;
NSString *urlString = url.absoluteString;
NSLog(urlString);
}
return YES;
}//end
Everytime my webview loads I DO get the "Loaded" in my logs, so I know that the delegate method is getting called. But I can never click on a link within my UIWebView and have anything happen. It does not even look like it is allowing a pressed state on the link. The link is highlighted like a link, just won't allow clicking.
Ideas?

The reason for the UIWebView not responding to touch events is most probably this line:
webView.opaque = NO;
Try setting opaque to YES.
My understanding is that for a view to respond to touch events, that view has to be returned by the call to hitTest:withEvent: during the view hierarchy traversal performed by the event delivery mechanism.
From the hitTest:withEvent: documentation:
This method ignores view objects that are hidden, that have disabled user interaction, or have an alpha level less than 0.01.
Update
Based on new info: if the UIWebView is embedded in a UIScrollView, quote from the Apple docs:
Important: You should not embed UIWebView or UITableView objects in UIScrollView objects. If you do so, unexpected behavior can result because touch events for the two objects can be mixed up and wrongly handled.

Please try with following code
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
if(navigationType==UIWebViewNavigationTypeLinkClicked)
{
[[UIApplication sharedApplication]openURL:request.URL];
return NO;
}
return YES;
}

Related

Press a Button and open a URL in another ViewController

I am trying to learn Xcode by making a simple app.
But I been looking on the net for hours (days) and I cant figure it out how I make a button that open a UIWebView in another ViewController :S
first let me show you some code that I have ready:
I have a few Buttons om my main Storyboard that each are title some country codes like UK, CA and DK.
When I press one of those Buttons I have an IBAction like this:
- (IBAction)ButtonPressed:(UIButton *)sender {
// Google button pressed
NSURL* allURLS;
if([sender.titleLabel.text isEqualToString:#"DK"]) {
// Create URL obj
allURLS = [NSURL URLWithString:#"http://google.dk"];
}else if([sender.titleLabel.text isEqualToString:#"US"])
{
allURLS = [NSURL URLWithString:#"http://google.com"];
}else if([sender.titleLabel.text isEqualToString:#"CA"])
{
allURLS = [NSURL URLWithString:#"http://google.ca"];
}
NSURLRequest* req = [NSURLRequest requestWithURL:allURLS];
[myWebView loadRequest:req];
}
How do I make this open UIWebview on my other Viewcontroller named myWebView?
please help a lost man :D
Well, you've firstViewController already designed and coded, now you've to create secondViewController with a UIWebView binded in IB it self, also it have a setter NSString variable like strUrl that you need to pass at the time of pushing or presenting secondViewController, and assign it to UIWebView in viewDidLoad of secondViewController. See my answer about how to pass a NSString? Also UIWebView has its delegates method (What's delegate & datasource methods? - Apple Doc) Which you can use to handle URL request.
These are the delegate of UIWebView, if you'll going to use it, you need to give UIWebView delegate to self.
- (void)webViewDidStartLoad:(UIWebView *)webView;
- (void)webViewDidFinishLoad:(UIWebView *)webView;
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error;
firstViewController.m
- (IBAction)ButtonPressed:(UIButton *)sender {
NSURL* allURLS;
//get your URL
secondViewControlelr *secondView=[[secondViewControlelr alloc]init];
second.urlToLoad=allURLS;
[self.navigationController pushViewController:secondView animated:YES];
}
secondViewControlelr.h
//declare url and set property
NSURL *urlToLoad;
secondViewControlelr.m
- (void)viewDidLoad
{
myWebView=[[UIWebView alloc]initWithFrame:CGRectMake(0, 0, 320, 460)];
[self.view addSubview:myWebView];
NSURLRequest *urlReq=[NSURLRequest requestWithURL:self.urlToLoad cachePolicy:NSURLCacheStorageNotAllowed timeoutInterval:10];
[myWebView loadRequest:urlReq];
}

Xcode 4.3 from a button in a UIWebView open the same url in safari

I am relatively new to Xcode and I have started building an app that uses UIWebView. To make it compliant for App Store submission, Apple prefers you use Safari. To overcome this problem I want to add a button to my UIWebView navigation that, when clicked, will open the same url in Safari. An example of this can be seen in the Twitter app; they have a button that opens the currently viewed UIWebView in a Safari window.
You can use the UIWebViewDelegate's method
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
if iWantToOpenThisURLInSafari([request URL]) {
[UIApplication openUrl:[request URL]];
return NO; // tell the webView to not navigate to the URL, I'm handling it
} else {
return YES;
}
}
- (BOOL)iWantToOpenThisURLInSafari:(NSURL* url) [
// you just have to fill in this method.
return NO;
}
http://developer.apple.com/library/ios/#documentation/uikit/reference/UIWebViewDelegate_Protocol/Reference/Reference.html#//apple_ref/occ/intf/UIWebViewDelegate
EDIT: more details as requested by #PaulGraham
// You have a pointer to you webView somewhere
UIWebView *myWebView;
// create a class which implements the UIWebViewDelegate protocol
#interface MyUIWebViewDelegate:NSObject<UIWebViewDelegate>
// in this class' #implementation, implement the shouldStartLoad..method
#implementation
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
if iWantToOpenThisURLInSafari([request URL]) {
[UIApplication openUrl:[request URL]];
return NO; // tell the webView to not navigate to the URL, I'm handling it
} else {
return YES;
}
}
// then, set the webView's delegate to an instance of that class
MyUIWebViewDelegate* delegate = [[MyUIWebViewDelegate alloc] init];
webView.delegate = delegate;
// your delegate will now recieve the shouldStartLoad.. messages.

Need tap gesture method after UIwebView shouldStartLoadWithRequest delegate invocation

My Problem is I have a webView inside the UIView and UIView have tap gesture and web view class having delegate of UIWebView.
My problem is when i tap on a link it first call tap then shouldStartLoadWithRequest . So i need to prevent calling of code which is written for tap on view.
Any one having any idea............
Edit
code for web view delegate
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
if(navigationType == UIWebViewNavigationTypeLinkClicked)
{
self.isAnyLinkTapped = YES;
RELEASE(webURL);
webURL = [[NSString stringWithFormat:#"%#",[request.URL absoluteString]] retain];
NSArray *urlCoponents = [[request.URL absoluteString] componentsSeparatedByString:#"/"];
if([urlCoponents count]>0)
{
//Some code here
}
}
}
i have add tap gesture like this
_tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapped:)];
and on tapping below code is invoking.
- (void) tapped:(UITapGestureRecognizer *) recognizer {
touchPointLocationForTap = [recognizer locationInView:recognizer.view];
[(WebViewController*)delegate setIsScreenTouched:YES];
BOOL isThereAnySelection = [self isThereAnyTextSelectionOnWebView];
if (!isThereAnySelection)
[self performSelector:#selector(sendTapEventToWebController) withObject:nil afterDelay:1.2];
}
Please post some code so that everybody can understand..
By the way-
you can identify view which was touched by using this condition
if([[touches view] isKindOfClass:[UIWebView class]]){
//Do whatever you want to do with webview
}else{
//Rest of the code
}

UIWebView in UIView need links to open up in browser

So i have an app that is not so much a webapp but more uses UIViewControllers and UIViews for most screens. On one particular controller i have a UIWebView control that only occupies a small portion of the UIViewController screen real estate that i load html from a web service as a string.
[self.webView loadHTMLString:marketingBlurb baseURL:nil];
what i'm wondering is if the html links in this string can open up on the browser and not in the UIWebView in my app???? How can i do this?? Is this even possible ?
Set the delegate of the webview to self, and intercept all links using webView:shouldStartLoadWithRequest:navigationType:
You can then call [UIApplication openURL] to open Safari.
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
if (navigationType == UIWebViewNavigationTypeLinkClicked) {
[[UIApplication sharedApplication] openURL:[request URL]];
return NO;
}
return YES;
}
I didn't test this code, but it will get you started.

How to show a loading message while UIWebView loads it's content?

I want to put a big spinner along with a "Loading message..." or a gif image, when UIWebView loads its contents so it won't just show a blank view. How should I do it?
implement UIWebview's delegate method put this code in it
- (void)webViewDidStartLoad:(UIWebView *)webView {
[activityIndicator startAnimating];
myLabel.hidden = FALSE;
}
- (void)webViewDidFinishLoad:(UIWebView *)webView {
[activityIndicator stopAnimating];
myLabel.hidden = TRUE;
}
set ActivityIndicater's Hidden when stop property to TRUE
Implement the UIWebView Delegate as outlined in Mihir's answer above but don't forget to assign the delegate otherwise the delegate methods will not be triggered
For example In ViewDidLoad you should add:
self.myWebView.delegate = self;