I am trying to pass a String from an IBAction in my DetailsViewController to the viewDidLoad in my WebViewController to call up a URL in the WebView.
Does anybody know how I can do this?
My Code:
// DetailsViewController.m
- (IBAction)edu1Link:(id)sender {
NSString *webURL = [[NSString webURL] initWithString:#"http://www.apple.com"];
_webViewController = [[WebViewController alloc]
initWithNibName:#"WebViewController" bundle:nil];
[[self navigationController] presentModalViewController:_webViewController animated:YES];
}
// WebViewController.m
- (void)viewDidLoad
{
[_webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:webURL]]];
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
You could declare a property in your WebViewController and set that property in the action before presenting the view controller.
I guess the best way would be to use a delegate methode
here is a tutorial how you would do that
What albertamg is referring to is Objective-C properties. They are very powerful. Take a peak here: http://cocoacast.com/?q=node/103
Properties are like instance fields in Java. They're helpful in side-stepping zero-parameter-methods.
Related
I want to have a UITableViewController controlling my TableView.
Where (and how) should I call init on the UITableViewController?
EDIT
Here's my current code inside my prepareForSegue method:
UINavigationController *navigationController = (UINavigationController *)self.window.rootViewController;
ReccyTableViewController *tableViewController = (ReccyTableViewController *)[[navigationController viewControllers] objectAtIndex:0];
ProjectDataController *aDataController = [[ProjectDataController alloc] init];
[tableViewController setDataController:aDataController];
[self presentViewController:tableViewController animated:YES completion:nil]; //Fails here
EDIT #2
Here's what I did in the end:
I scrapped trying to init the datacontroller in the prepareForSegue method and did it in the viewDidLoad method instead:
- (void)viewDidLoad
{
[super viewDidLoad];
_dataController = [[ProjectDataController alloc] init];
}
this may help you
read apple official docs
You should call it from the point of your previous controller from where you want to add/push this tableViewController.
So I am writing an app that will read a JSON feed. In my application:didFinishLaunchingWithOptions, I am writing some code to download the JSON string and store it into a local NSString variable. I will then pass that string into ListingsViewController (which is the Root VC of the NavigationController). When I print out the JSON data in ListingsViewController, it is showing me (null) which is making me think that viewDidLoad is loading before - which seems illogical?
So here is my application:didFinishLaunchingWithOptions
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Grab the feeds
NSURL *jsonURL = [NSURL URLWithString:#"http://www.shoofeetv.com/iphonexml/view/all_channels.json"];
NSString *jsonData = [[NSString alloc] initWithContentsOfURL:jsonURL];
// Pass jsonData to the ListingsViewController
ListingsViewController *listingsViewController = [[ListingsViewController alloc] initWithNibName:#"ListingsViewController" bundle:nil];
listingsViewController.jsonData = jsonData;
[listingsViewController release];
// Display the navigation controller
self.window.rootViewController = self.navigationController;
[self.window makeKeyAndVisible];
return YES;
}
My viewDidLoad method is as follows:
- (void)viewDidLoad {
self.navigationItem.title = #"Listings";
UIBarButtonItem *checkinButton = [[UIBarButtonItem alloc]
initWithTitle:#"Check In"
style:UIBarButtonItemStylePlain
target:self
action:#selector(switchView)];
self.navigationItem.rightBarButtonItem = checkinButton;
[checkinButton release];
NSLog(#"%#", self.jsonData);
[super viewDidLoad];
}
Please note that a common solution is to make sure that the App Delegate in MainWindow.xib must be connected to the File's Owner. Mine already is connected.
I will appreciate any help!
Thank you everyone.
well you are setting up a view controller with your code, but it is never shown within the navigation controller. you just set up a view controller, assign its jsonData a string and destroy the view controller immediately. I#m pretty sure the output you get is from a different view controller that you create in your main XIB.
what you want to do is create an empty navigation controller in your XIB and then do the following:
// Pass jsonData to the ListingsViewController
ListingsViewController *listingsViewController = [[ListingsViewController alloc] initWithNibName:#"ListingsViewController" bundle:nil];
listingsViewController.jsonData = jsonData;
[self.navigationController pushViewController:listingsViewController animated:NO];
[listingsViewController release];
// Display the navigation controller
self.window.rootViewController = self.navigationController;
[self.window makeKeyAndVisible];
this will actually display the view controller you created.
Also remember that when you deploy your application, you need to load your json-data asynchronously and handle network errors (apple will test your app under various network conditions)
I have a TableViewController which is supposed to load a ViewController with a WebView in it when I select a cell.
Here's the code :
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
PostViewController *postViewController = [[PostViewController alloc] initWithNibName:#"PostViewController" bundle:[NSBundle mainBundle]];
[postViewController.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:#"http://www.google.fr"]]]
[self.navigationController pushViewController:postViewController animated:YES];
[PostViewController release];
}
The problem is that the ViewController is loaded but nothing happens in the WebView.
When I debug the program I can see that the WebView's address is 0x0 so I guess something's wrong.
Is it because I try to modify the content of the WebView before its parent ViewController is loaded ?
I guess another way to do it properly would be to pass the URL to the ViewController and then to call loadRequest on the WebView from inside the viewWillAppear method.
But I need to understand why it doesn't work this way.
Try this
Instead of accessing the WebView why dont you just pass the URL value to the ViewController and load the Webview in the viewDidLoad of postViewController.
In your case
PostViewController *postViewController = [[PostViewController alloc] initWithNibName:#"PostViewController" bundle:[NSBundle mainBundle]];
postViewController.urlString = #"http://www.google.fr";
[self.navigationController pushViewController:postViewController animated:YES];
[PostViewController release];
In your postViewController.h declare the urlString with properties and synthesize in the .m file
Now in your viewDidLoad
//Alloc init your webview here
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:urlString]]];
0x0 is the address of nil, meaning that your web view has not been initialized at this point.
If you're creating your web view in the loadView or viewDidLoad methods of PostViewController, then calling setNeedsLayout immediately after initialization will force its creation:
PostViewController *postViewController = [[PostViewController alloc] init ...
[postViewController.view setNeedsLayout];
Otherwise, these methods will not be called until your view is displayed.
I encountered some strange memory leaks executing following code on iPhone device:
#implementation TestViewController
#synthesize myButton;
- (IBAction)buttonPressed {
ABPeoplePickerNavigationController* selectContactViewController = nil;
selectContactViewController = [[ABPeoplePickerNavigationController alloc] init];
selectContactViewController.peoplePickerDelegate = self;
[self presentModalViewController:selectContactViewController animated:YES];
[selectContactViewController release];
}
Releasing the picker simple done as follows:
- (void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker {
[self dismissModalViewControllerAnimated:YES];
}
Instruments marks "selectContactViewController = [[ABPeoplePickerNavigationController alloc] init];" as leaking. Any idea why?
You might want to construct your Picker control like so:
ABPeoplePickerNavigationController* selectContactViewController = nil;
selectContactViewController = [[[ABPeoplePickerNavigationController alloc] init] autorelease];
selectContactViewController.peoplePickerDelegate = self;
[self presentModalViewController:selectContactViewController animated:YES];
When you present the modal view controller, it will retain the view on its own. That's how it's able to still pass you an instance of the view controller to your delegate. Best bet is to set the view controller to be autoreleased, so when it gets popped from the navigation controller, the NSAutoReleasePool will garbage collect it.
Just a comment - do you use any protocol like UINavigationControllerDelegate in the interface declaration?
I encountered a situation where just referencing this protocol caused a similar leak message.
Looking at the UIWebView docs, it says that
Before releasing an instance of UIWebView for which you have set a delegate, you must first set the UIWebView delegate property to nil before disposing of the UIWebView instance. This can be done, for example, in the dealloc method where you dispose of the UIWebView
I'm creating a webview on the fly on a UITableView cell tap. I'm not sure how to do the "set delegate to nil" bit, since I don't track the UIWebView after its pushed to the navigation stack. I would have though that the UIWebView's dealloc method would be calling release on the delegate anyway?
Here's what I'm doing:
UIWebView *webView = [[UIWebView alloc] init];
UIViewController *viewController = [[UIViewController alloc] init];
// Start the webview loading, etc
...
// set the delegate
[webView setDelegate:self];
// Add the webview to the viewcontroller
[viewController setView:webView];
[[self navigationController] pushViewController:viewController animated:YES];
[webView release];
[viewController release];
I get the impression that I should write
[webView release];
[viewController release];
[self release]; // Releasing the delegate as per the docs.
But that seems kind of awkward, or have I interpreted it correctly?
No. webView doesn't release/retain it's delegate it only assign it
UIWebView.h :
#property(nonatomic,assign) id<UIWebViewDelegate> delegate;
You can check [self retainCount] before and after [webView setDelegate:self]
It'll be the same
Just spotted this, old now but maybe an answer will be useful to someone.
The docs are correct, you should set the delegate reference to nil before releasing the webview.
In your code example, you would subclass UIViewController, and in the subclass override the -dealloc method to include a nullify of the view delegate.
For example:
- (void)dealloc {
// Clear the webview delegate
self.view.delegate = nil;
[super dealloc];
}
HTH