Catching modal UIWebView links touches - iphone

I have a view controller and I am intercepting the touches on links within the web views it manages.
My main view controller has this method.
- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType
{
//I can see this request come in upon a touch
NSURL *url = request.URL;
NSString *urlString = url.absoluteString;
NSLog(#"raw: %#", urlString);
//do some stuff (like figure out what capturedFilename is)
ExplainViewController *explanation = [[ExplainViewController alloc] initWithNibName:#"ExplainViewController" bundle:nil file:capturedFilename];
[self.navigationController presentModalViewController:explanation animated:YES];
}
And this loads a modal view properly.
ExplainViewController has a webView itself. When a user touches a link within ExplainViewConroller I'd like to handle that request too (and present another modal view).
ExplainViewController has this but I get no log activity from either method (the following nor the previous):
- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType
{
NSURL *url = request.URL;
NSString *urlString = url.absoluteString;
NSLog(#"raw: %#", urlString);
}
I want to know where this link touch request is going and how I can intercept it.
Both mentioned view controllers are using this in their .h
<UIWebViewDelegate>

You mention that both view controllers conform to the UIWebViewDelegate protocol, but is the delegate outlet of the UIWebView in the nib for ExplainViewController.h set to an instance of ExplainViewController. It will not call the method unless the UIWebView delegate property is set.

- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType {
if (navigationType == UIWebViewNavigationTypeLinkClicked) {
BrowserController *browserController = [[BrowserController alloc] initWithUrl:request.URL.absoluteString];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:browserController];
[self.navigationController presentModalViewController: navController animated:YES];
[browserController release];
[navController release];
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];
}

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
}

Passing a URL from one UIWebView to another UIWebview

When a user clicks a link in the present UIWebView a new view is pushed onto the navigationController's stack that contains a UIWebView. I'd like to pass the URL that was touched to this new UIWebView. How do I go about doing this?
In your UIWebView delegate:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
if( navigationType == UIWebViewNavigationTypeLinkClicked ) {
YourWebViewController* vc = [[YourWebViewController alloc] initWithURL:[request URL]];
[self.navigationController pushViewController:vc animated:YES];
[vc release];
return NO;
}
return YES;
}
Then you just need to implement the initializer in your custom viewcontroller:
- (id)initWithURL:(NSURL*)url {
self = [super init];
if( self ) {
myURL = [url retain];
}
return self;
}
Then load it at an appropriate time, like viewDidAppear:
- (void)viewDidAppear:(BOOL)animated {
[webView loadRequest:[NSURLRequest requestWithURL:myURL]];
}

How can I dismissModalViewController when a user hits GO?

I have a view and a button. When the button is pushed, I present a modal view controller that has a uiwebview, and a navigation bar at the top. The hardcoded uiwebview shows a login prompt. Once the user goes in and enters the correct login credentials and hits GO on the keyboard, I not only need it to authenticate me into the server, but also dismiss the modal view controller.
Note the text field I enter data into is part of the website loaded in uiwebview...
When I hit enter now, the web page authenticates, and everything is peachy, but I just need a way to tie in a
[self dismissModalViewControllerAnimated:YES];
command when they hit GO...any thoughts?
Thanks
EDIT
Here is the code that I am implementing in the loginView:
- (void)viewDidLoad {
[super viewDidLoad];
NSURL *url = [[NSURL alloc] initWithString: #"http://website"];
NSURLRequest *request = [[NSURLRequest alloc] initWithURL: url];
[webView loadRequest: request];
[request release];
[url release];
}
-(BOOL) textFieldShouldReturn:(UITextField *)textField{
[self dismissModalViewControllerAnimated:YES];
return YES;
}
-(IBAction) done{
[self dismissModalViewControllerAnimated:YES];
}
First determine the URL the webpage takes you to on successful login, let's say it's http://website/logedin. Implement UIWebViewDelegate, and detect when a request is made to that address:
- (BOOL)webView:(UIWebView *)wv shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
if ([[request.URL absoluteString] isEqualToString:#"http://website/logedin"]) {
[self dismissModalViewControllerAnimated:YES];
return NO;
}
return YES;
}
you can try with below sample code;
#interface WebViewController : UIViewController {
}
UIWebViewDelegate having few delegate methods, you have to implement it in WebViewController.m (for eg).
-(void) webViewDidStartLoad:(UIWebView *)webView{
}
-(void) webViewDidFinishLoad:(UIWebView *)webView{
-(void) webViewDidFinishLoad:(UIWebView *)webView
}
-(void) webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error{
}
Before this, you have to set the delegate for UIWebView from Interface Builder.

Throwing webview request to another webview

I have a UIViewController with a UIWebView (webview1) in it. The webview is only a few lines of text but does have a link in it. Rather than open the link, which goes to an external website, in this tiny space, I'd like to send it on to webview2, which will be a full screen. The goal is to keep the web requests within my app rather than Safari. Instead of creating another controller for webview2, I'd like to use webview1's controller.
In Webview1Controller controller, I do this in webViewLoad:
webview1.delegate = self;
Here's where I hand off the web request to webview2, which works fine:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
myapp *delegate = [[UIApplication sharedApplication] delegate];
Webview1Controller *webview1Controller = [[Webview1Controller alloc] initWithNibName:#"webview2" bundle:nil];
//self.view = webview2;'
[delegate.navigationController pushViewController: webview1Controller animated:YES];
[webview1Controller.webview2 loadRequest:request];
[webview1Controller release];
return YES;
}
In Interface Builder, I have webview2.xib File's Owner class set to Webview1Controller. It's "view" and the webview2outlet are connected. I have an IBOutlet in Webview1Controller named webview2outlet.
When i go back to webview1, it has also loaded the same request. Is there a way to stop webview1 from loading anything? If I return NO in the above method, webview1 won't render my content.
One solution is just to reload webview1 content on viewWillAppear, which works. But is there a better way?
Return NO from the delegate method.
Regarding your comment, I think what you want to do is make your delegate method check which webview is calling your controller:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
if (webView == webview1) {
Webview1Controller *webview1Controller = [[Webview1Controller alloc] initWithNibName:#"webview2" bundle:nil];
[self.navigationController pushViewController:webview1Controller animated:YES];
[webview1Controller.webview2 loadRequest:request];
[webview1Controller release];
return NO;
}
else {
return YES;
}
}
(Note, also, that UIViewController has a navigationController property so you can use that rather than getting it through your app delegate).
What happens if you load a copy of the request instead of the original, and then return NO?
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
myapp *delegate = [[UIApplication sharedApplication] delegate];
Webview1Controller *webview1Controller = [[Webview1Controller alloc] initWithNibName:#"webview2" bundle:nil];
//self.view = webview2;'
[delegate.navigationController pushViewController: webview1Controller animated:YES];
[webview1Controller.webview2 loadRequest:[[request copy] autorelease]];
[webview1Controller release];
return NO;
}