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];
}
Related
I use webview in my UIVIewController and load the local HTML file in it using following method.
[self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:filePath]]];
If I put this method in ViewDidLoad, I can see white flicking while navigating to my controller that doesn't look good.
I tried putting this method in ViewWillAppear like below. I am using webViewLoaded flag to make sure that webview has been loaded then only show the current view else it waits but it is going in infinite loop of waiting!
- (void)viewWillAppear:(BOOL)animated {
webViewLoaded = NO;
webView.scalesPageToFit = allowZoom;
webView.dataDetectorTypes = UIDataDetectorTypeNone;
webView.delegate = self;
[self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:filePath]]];
int count = 0;
while(webViewLoaded == NO)
{
NSLog(#"Waiting...");
[NSThread sleepForTimeInterval:0.1];
if(count++ > 10) break;
}
}
- (void)webViewDidFinishLoad:(UIWebView *)localwebView {
webViewLoaded = YES;
}
I have also tried the same thing in ViewDidLoad but still its going in infinite loop.
Please note that webViewLoaded is "volatile BOOL" but the webview delegate method is not getting called. Not sure what's going on!
Could anyone please help me to fix this. Thanks.
First : You're blocking your main thread and not giving WebView any chance to finish loading. Never block your main thread.
Second : There are two UIWebView delegate methods : webViewDidFinishLoad and webView:didFailLoadWithError: - make sure to listen to both.
If you're trying to wait until WebView completes loading and only show your controller afterwards - use delegation or blocks. Please note that this is not a proper way of doing things - i'm just modifying your example to make it work :
child controller (with WebView) :
-(void)startLoadingWithParent:(id)_parent {
self.parent = _parent;
NSURL * url = [[NSBundle mainBundle] URLForResource:#"resource" withExtension:#"html"];
[webView loadRequest:[NSURLRequest requestWithURL:url]];
}
-(void)webViewDidFinishLoad:(UIWebView *)webView {
[parent showMe:self];
}
-(void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
[parent showError:error];
}
master controller :
-(void)doSomething {
SecondController * ctrl; /// secondController should be created AND has its view loaded at this point
/// ctrl = [SecondController new];
/// ctrl.view;
[ctrl startLoadingWithParent:self];
/// show user that we're doing something - display activity indicator or something
}
-(void)showMe:(UIViewController*)me {
[self.navigationController pushViewControllerAnimated:me];
}
Try using [NSURL fileURLWithPath:filePath]
use Following code for
[self performSelectorInBackground:#selector(webViewLoaded) withObject:nil];
so that it will not affect your UI
I currently have the following code that loads a UIWebView from another View. Now is there anyway I can have a close button?
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UIWebView *webView=[[UIWebView alloc] initWithFrame:CGRectMake(0,0,320,480)];
[self.view addSubview:webView];
NSURLRequest *urlRequest;
NSURL *urlforWebView;
urlforWebView=[NSURL URLWithString:#"http://www.google.com"];
urlRequest=[NSURLRequest requestWithURL:urlforWebView];
[webView loadRequest:urlRequest];
}
I am going to load a page built using jquery mobile, so a close button inside the page would also work fine. But on a navigation bar would be ideal. Btw, my application does not have a UINavigationBar
I would create a new sub class of UIViewController, say WebViewController with a nib. Then I would add an UINavigationBar with a close button and an UIWebView. Then to show your web view controller you can do something like:
WebViewController *webViewController = [[WebViewController alloc] init];
webViewController.loadURL = [NSURL URLWithString:#"http://www.google.com"];
[self presentModalViewController:webViewController animated:YES];
[webViewController release];
In your WebViewController you can define:
#property (nonatomic, retain) IBOutlet UIWebView *webView;
#property (nonatomic, retain) NSURL *loadURL;
- (IBAction)close:(id)sender;
and implement something like this:
- (void)viewDidLoad {
[super viewDidLoad]
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:self.loadURL];
[self.webView loadRequest:urlRequest];
}
- (IBAction)close:(id)sender {
[self dismissModalViewControllerAnimated:YES];
}
Whenever you load the UIWebView, you could run a javascript snippet on the content first.
[webView stringByEvaluatingJavaScriptFromString:#"window.close = function() { window.location = 'app://close-webview'; };"];
That just hijacks the normal behavior of window.close() and gives you chance to catch the call in your Objective-C.
Then in your UIWebViewDelegate you could listen for whatever you chose as the close url.
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
if([request.URL.absoluteString isEqualToString:#"app://close-webview"]) {
webView.hidden = YES;
// or whatever you want to do to remove the UIWebView...
return NO;
}
return YES;
}
A bit hackish, but it would allow the web developer to control the look and feel of the close button from within the HTML content.
I have one view holding a list of videos(buttons which can be clicked, each hold a url) which currently bring up a new view which holds the UIWebview, the only problem is I cant pass the url to the webview depending on which button was clicked.
At the moment I just get an empty UIWebview.
How can the url string be passed to the webview so it can load the correct url for each button?
Regards
NSURL *videoURL = [NSURL URLWithString:#"http://..."];
[webView loadRequest:[NSURLRequest requestWithURL:videoURL]];
UPDATE:
In response to comment #3, here's what you can do:
This goes without saying, but keep a reference to the UIWebView instance in Browser
Add an NSString or NSURL #property to Browser
Pass the URL to the Browser instance right after init
In viewDidLoad:, call loadRequest:
So your code might look like this:
- (void)buttonClicked {
Browser *browser = [[Browser alloc] initWithNibName:nil bundle:nil];
browser.URL = [NSURL URLWithString:#"http..."];
[self presentModalViewController:browser animated:YES];
[browser release];
}
and in Browser's viewDidLoad:
- (void)viewDidLoad {
[super viewDidLoad];
[webView loadRequest:[NSURLRequest requestWithURL:URL]];
}
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;
}
In my iPhone app an UITextView is containing an URL. I want to open this URL in an UIWebView instead of opening it into safari?
My UITextView contains some data along with an URL. In some cases the no. of URLs can be more than one.
Thanks
Sandy
You can follow these steps:
Tick on the following properties in UITextView taken from Xib or Storyboard.
OR write these for textview taken dynamically.
textview.delegate=self;
textview.selectable=YES;
textView.dataDetectorTypes = UIDataDetectorTypeLink;
Now write the below delegate method :
-(BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange
{
NSLog(#"URL: %#", URL);
//You can do anything with the URL here (like open in other web view).
return NO;
}
I think you are searching for that.
The UITextView has the capability to detect URLs and embed hyperlinks accordingly. You can turn that option on in:
myTextView.dataDetectorTypes = UIDataDetectorTypeLink;
Then you need to configure your app to trap this URL request and let your application handle it. I published a boilerplate class on github that does this, which might be the easiest route: http://github.com/nbuggia/Browser-View-Controller--iPhone-.
The first step is to sub-class UIApplication so you can override who gets to take action on the 'openUrl' request. Here's what that class might look like:
#import <UIKit/UIKit.h>
#import "MyAppDelegate.h"
#interface MyApplication : UIApplication
-(BOOL)openURL:(NSURL *)url;
#end
#implementation MyApplication
-(BOOL)openURL:(NSURL *)url
{
BOOL couldWeOpenUrl = NO;
NSString* scheme = [url.scheme lowercaseString];
if([scheme compare:#"http"] == NSOrderedSame
|| [scheme compare:#"https"] == NSOrderedSame)
{
// TODO - Update the cast below with the name of your AppDelegate
couldWeOpenUrl = [(MyAppDelegate*)self.delegate openURL:url];
}
if(!couldWeOpenUrl)
{
return [super openURL:url];
}
else
{
return YES;
}
}
#end
Next, you need to update main.m to specify MyApplication.h as being the bonified delegate for your UIApplication class. Open main.m and change this line:
int retVal = UIApplicationMain(argc, argv, nil, nil);
to this
int retVal = UIApplicationMain(argc, argv, #"MyApplication", nil);
Finally, you need to implement the [(MyAppDelegate*) openURL:url] method to have it do what ever you would like with the URL. Like maybe open up a new view controller with a UIWebView in it, and show the URL. You could do something like this:
- (BOOL)openURL:(NSURL*)url
{
BrowserViewController *bvc = [[BrowserViewController alloc] initWithUrls:url];
[self.navigationController pushViewController:bvc animated:YES];
[bvc release];
return YES;
}
Hopefully that should work for you.
Assuming you have the following instances, that are also added to your UIView:
UITextView *textView;
UIWebView *webView;
and textView contains the URL string, you can load the contents of the URL into webView, as follows:
NSURL *url = [NSURL URLWithString:textView.text];
NSURLRequest *req = [NSURLRequest requestWithURL:url];
[webView loadRequest:req];