Unable to load new URL to UIWebView from another controller - ios

I am new to iOS and I'm trying to make an webview-based app with sidebar drawer and simple navigation (I'm using MFSideMenu library). I'm able to load URL with my webview:
ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController <UIWebViewDelegate>{
UIWebView *webView;
}
#property (retain, nonatomic) IBOutlet UIWebView *webView;
- (IBAction)showLeftMenuPressed:(id)sender;
- (void) loadURL;
#property (nonatomic, strong) NSURL *url;
#end
ViewController.m
#import "ViewController.h"
#import "MFSideMenu.h"
#interface ViewController ()
- (void)webViewDidFinishLoad:(UIWebView *)webView;
#end
#implementation ViewController
#synthesize webView;
#synthesize url;
- (void)viewDidLoad
{
[super viewDidLoad];
webView.delegate=self;
if(self.url == Nil) {
NSString *myURL = #"http://google.com/";
self.url = [NSURL URLWithString:myURL];
}
[self loadURL];
}
-(void)loadURL{
NSLog(#"loadURL: %#", self.url);
[self.webView loadRequest:[NSURLRequest requestWithURL:self.url]];
}
When I'm trying to load new URL using following code, I'm receiving right url param value. Another controller is a sidebar (drawer) tableview where I'm selecting an item to change the URL showing in the main view (ViewController which contains webview).
Another controller:
ViewController *webViewController = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
NSString *urlString = #"http://kirk.kh.ua/";
NSString *encodedString=[urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url = [NSURL URLWithString:encodedString];
webViewController.url = url;
//[self.navigationController pushViewController:webViewController animated:YES];
[webViewController loadURL];
[webViewController release];
You may notice that there is a commented line - I have tried this solution, but result is the same: when I'm calling code in another controller nothing happens with the ViewController's webview which is strange because in log output I see that loadURL method was called and it gives me a right URL (kirk.kh.ua).
UPD: I have noticed that on the first load webview as an object, and then it appears to be null (see log):
UPD2: I have noticed that webivew object and other synthesized objects are null when I'm calling them from another class, but this objects exist and accessible when I'm logging them from self (ViewController) controller.
Can anyone suggest how can I access ViewController class objects from another class?

Instead of trying to open the URL from the Another Controller - make a NSString property in the ViewController, then when you tap a cell just pass the URL as a string:
ViewController *webViewController = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
webViewController.urlString = #"http://kirk.kh.ua/";
And then add in the ViewController add something like this in the viewWillAppear:
if (![self.urlString isEqualToString:#""]) {
NSString *encodedString=[urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url = [NSURL URLWithString:encodedString];
webViewController.url = url;
[webViewController loadURL];
}

Related

call functions on a uiwebview controller outside the Viewcontroller class in objective C

I have a uiwebview in my ios program and it is connected to a variable inside the ViewController interface
#interface ViewController() <UIWebViewDelegate>
#property(weak, nonatomic) IBOutlet UIWebView *uiwebview;
#end
I want to call functions on this uiwebview from outside the viewcontroller
For example, I can control the webview just fine if it is used between
#implementation ViewController
.
.
.
#end
But I want to use it somewhere outside. For example, I want to do something like this
[uiwebview loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:#"about:blank"]]];
from outside #implementation ViewController
What are the options to achieve this?
But I want to use it somewhere outside. For example, I want to do something like this
[uiwebview loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:#"about:blank"]]];
from outside #implementation ViewController
Stop wanting that. An IBOutlet should be private to its own view controller. If you want other view controllers to be able to do something to that web view, then arm your ViewController with public methods that they can call.
I think I understand what you are trying to do, I have an app that has various tabs some of which are web view. When my app starts I get it to pre-load the web views so that when the tabs are selected they are already loaded. Its important the the other tabs are all singleton classes so that there is only one instance of them.
In my main ViewController viewDidLoad I have this ..
//Pre load calculators and status page
EvolutionViewController *evoCalc = [EvolutionViewController sharedInstance];
[evoCalc.view layoutSubviews];
IVCalcViewController *ivCalc = [IVCalcViewController sharedInstance];
[ivCalc.view layoutSubviews];
StatusViewController *serverStatus = [StatusViewController sharedInstance];
[serverStatus.view layoutSubviews];
Those instantiate the classes for the other tabs which also loads up the web views associated with those classes. All the classes are similar this is the .h
#import <UIKit/UIKit.h>
#interface EvolutionViewController : UIViewController <UIWebViewDelegate>
+ (EvolutionViewController *) sharedInstance;
#property (nonatomic, retain) IBOutlet UIWebView *webView;
#end
And the .m
#import "EvolutionViewController.h"
#interface EvolutionViewController ()
#end
#implementation EvolutionViewController
#synthesize webView;
#pragma mark - Singleton Methods
static EvolutionViewController *_sharedInstance;
- (id) init
{
if (self = [super init])
{
// custom initialization
}
return self;
}
+ (EvolutionViewController *) sharedInstance
{
return _sharedInstance;
}
-(id)initWithCoder:(NSCoder *)decoder {
if (!_sharedInstance) {
if (self = [super initWithCoder:decoder]) {
_sharedInstance = self;
}
}
return _sharedInstance;
}
#pragma mark - View Controller Methods
-(void)viewWillLayoutSubviews {
self.webView = [[UIWebView alloc] init];
}
- (void)viewDidLoad {
[super viewDidLoad];
NSURL *url = [[NSBundle mainBundle] URLForResource: #"evo_calc" withExtension:#"html"];
NSURLRequest*request=[NSURLRequest requestWithURL:url];
[self.webView loadRequest:request];
}
#end
Mine uses local html resources but works the same with a proper URL as well.

How to access instance from another function in objective c?

I am trying to access a webView object from another class.
viewController.m
#property (strong, nonatomic) TOWebViewController *webViewController;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.webViewController = [[TOWebViewController alloc] initWithURLString:[NSString stringWithFormat:#"http://www.%#/", url] ];
[self setViewControllers:#[_webViewController]];
}
- (void)request {
NSURL *url=[NSURL URLWithString:#"http://www.google.com"];
NSURLRequest *request=[NSURLRequest requestWithURL:url];
[_webViewController.webView loadRequest:request];
}
TOWebViewController has the webView property to access the webview. When (void)request is called, something starts loading but it does not load it into the webview that was created in viewDidLoad. How do I have it reference the correct webViewController in (void)request?
I just looked at TOWebviewController on github and it states the following in TOWebViewController.h:
/**
The web view used to display the HTML content. You can access it through this
read-only property if you need to anything specific, such as having it execute arbitrary JS code.
#warning Usage of the web view's delegate property is reserved by this view controller. Do not set it to another object.
*/
#property (nonatomic,readonly) UIWebView *webView;
So the class doesn't sound like you need to interact with it by accessing it directly.
You more than likely want to just set the url:
/**
Get/set the current URL being displayed. (Will automatically start loading)
*/
#property (nonatomic,strong) NSURL *url;
So try:
- (void)request {
NSURL *url=[NSURL URLWithString:#"http://www.google.com"]
_webViewController.url = url;
}
You should try to use childViewController.
The reference document UIViewController Class Reference
Here are the essential methods you might need to call:
addChildViewController:
removeFromParentViewController:
willMoveToParentViewController:
didMoveToParentViewController:
My best guess is what you really want is to display the UIWebView inside the "parent" view controller, and that there is no need for a "child" view controller.
Why not do it like this?
#interface ViewController : UIViewController
#property (weak) IBOutlet UIWebView *webView; // set outlet in IB
#end
#implementation ViewController
// ...
- (void)request {
NSURL *url=[NSURL URLWithString: #"http://www.google.com"];
NSURLRequest *request = [NSURLRequest requestWithURL: url];
[self.webView loadRequest:request];
}
#end

retain viewcontroller - message sent to deallocated instance

I'm trying to use the UIWebViewDelegate, however, when I set delegate to it's self, I get a 'message sent to deallocated instance' error.
Actual error: "2014-04-07 22:12:05.402 AppName[746:60b] -[WebViewController respondsToSelector:]: message sent to deallocated instance 0xa47ae00"
I presume this is because the WebViewController instance has not been retained?
Could anyone point me in the right direction for this please?
My structure is:
RootViewController > WebViewController (delegate) > WebView
// root.h
#interface RootViewController : UIViewController
#property (strong, nonatomic) WebViewController * webViewController;
#end
// root.m
#import "RootViewController.h"
#import <UIKit/UIKit.h>
#import "WebViewController.h"
#interface RootViewController ()
#end
#implementation RootViewController
- (void)viewDidLoad
{
_webViewController = [[WebViewController alloc] init];
[self.view addSubview:_webViewController.view];
}
#end
// .h
#import <UIKit/UIKit.h>
#interface WebViewController : UIViewController <UIWebViewDelegate>
#property(strong) UIWebView *webView;
#end
// .m
#import "WebViewController.h"
#interface WebViewController ()
#end
#implementation WebViewController
- (void)viewDidLoad
{
_webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height)];
_webView.delegate = self;
NSString *url = #"http://google.com/";
NSURL *nsurl = [NSURL URLWithString:url];
NSURLRequest *nsrequest = [NSURLRequest requestWithURL:nsurl];
[_webView loadRequest:nsrequest];
[self.view addSubview:_webView];
}
-(void)webViewDidStartLoad:(UIWebView *)webView {
NSLog(#"ui web view started load");
}
Try moving your code out of loadView into viewDidLoad, and remove your calls to loadView. I believe loadView is called automatically when the view controller is instantiated and shown, so calling it again might cause you to instantiate your webview twice.
From the docs:
You should never call this method directly. The view controller calls
this method when its view property is requested but is currently nil.
This method loads or creates a view and assigns it to the view
property.
I had not set the root view controller like so:
self.window.rootViewController = rootController;

WebView shows only white although delegate is set and methods are being called

I have a viewcontroller that loads a webView in the view did load
#synthesize webView = _webView;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
self.webView = [[UIWebView alloc] init];
[self.webView setDelegate:self];
NSString *string = #"http://www.google.com";
NSURL *url = [NSURL URLWithString:string];
NSLog(#"The URL is %#", url);
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSLog(#"The request is %#", request);
NSLog(#"webview delegate is %#", self.webView.delegate);
NSLog(#"webview is %#", self.webView);
[self.webView loadRequest:request];
}
Everything is working fine when i debug meaning that nothing is returning nil. I declared the property in the .h file like this
#property (nonatomic, retain) IBOutlet UIWebView *webView;
I have also tried
#property (nonatomic, strong) IBOutlet UIWebView *webView;
and the WebView in IB is hooked up to delegate and this property. The problem is that no matter what url I try (I have tried them all in the browser), the web view only returns a white screen. All the delegate methods have been called, I know because I logged to the console. Does anyone know how to fix this or what I am doing wrong.
From your code -
#property (nonatomic, retain) IBOutlet UIWebView *webView;
Since you are connected webview to an outlet, the instance of webview is created after the unarchiving of your Nib.
So no need to instantiate webview again -
self.webView = [[UIWebView alloc] init];
Remove the above line from your code and test it. Should work!
Well, the fix for this issue seems to me pretty straightforward.
You're not setting any frame for your web view. Try the following:
self.webView = [[UIWebView alloc] initWithFrame:CGRectMake(0,0,500,500)];
Of course, the actual dimensions for your web view may vary. You'll have to adjust it yourself.
Update
I'm seeing that you're not adding the web view as a subview. Add the following line after the call to loadRequest:
[self.view addSubview:self.webView];
Hope this helps!

Example of WebView tool

I don't know how to create WebView control. I want to display any web page in a WebView, so how can I do this?
First create a view based application, in the View, add a UIWebView, and in the .plist add a Application Uses Wi-Fi key, and set it YES. In the ViewController class' .h file make the code look like this:
#import <UIKit/UIKit.h>
#interface ClassNameHere : UIViewController {
UIWebView *webView;
}
#property (nonatomic, retain) IBOutlet UIWebView *webView;
#end
In the .m file, add this code:
#synthesize webView;
- (void)viewDidLoad {
NSString *urlString = #"http://www.google.com";
//Create a URL object.
NSURL *url = [NSURL URLWithString:urlString];
//URL Requst Object
NSURLRequest *webRequest = [NSURLRequest requestWithURL:url];
//Load the request in the UIWebView.
[webView loadRequest:webRequest];
}
Finally, in your nib file, connect the webView outlet to the UIWebView. When you compile, it should open Google.

Resources