Accessing pushViewController's methods from popViewController - iphone

I am working on a view based application. In this i have two viewcontrollers. They are: Rootviewcontroller and Detailviewcontroller.
Now i am passing a values to Detailviewcontroller using pushViewController method.It works fine. But now when i pop out from this Detailviewcontroller i should access myfunction in Rootviewcontroller. Is it possible please suggest?
Any help would be apprecited !
-Sathiya

call myfunction in the root view controller's viewWillAppear:(BOOL)animated method or the viewDidAppear:(BOOL)animated method, depending on when you want it to be called. that way whenever that controller appears the code you need will be run.

I don't really understand your question 100%, but I think you want to access the methods of the Root ViewController from another View Controller further up the stack?
You can do something like this in DetailViewController:
RootViewController *rootViewController = (RootViewController*)self.navigationController.topViewController;
Now that you have a reference to the Root, you can call methods on it as you wish.

Store instance of rootViewController in AppDelegate.
// AppDelegate.h
RootViewController* rootViewController;
Add an access method to the implementation.
// AppDelegate.m
- (UIViewController*) GetRootViewController {
return rootViewController;
}
Call this method to get the rootViewController from anywhere in your app.
UIViewController* controller =
[(AppDelegate*)[[UIApplication sharedApplication] delegate] GetRootViewController];

Related

Where should I create and present a Modal ViewController used throughout iPhone application

I have an iPhone application that uses a UITabBarController for its primary interface. The application also makes heavy use of modal UINavigationControllers presented from the various tabs.
There is a ViewController that I need to present modally which can be triggered from a wide variety of locations within the application. It seems like a terrible idea to duplicate the code which creates and presents it between all the viewControllers that trigger it. I would like to have this code in a single place and trigger it from whichever viewController wants to present it.
Where should this centralised location be? My root ViewController is a UITabBarController so no good there, and I hate lumping view functionality into the AppDelegate.
I would create a new class file that has a function to present the view you want. That way you only need to write the code once to present the modal view and each view that needs to use it can call the function on the helper class with one line of code.
#interface ApplicationHelper : NSObject {
}
+(void)showMyModalView:(UIViewController *)parentViewController;
#end
Implementation:
#import "ApplicationHelper.h"
#import "ViewController.h"
#implementation ApplicationHelper
+(void)showMyModalView:(UIViewController *)parentViewController
{
ViewController *vc = [[ViewController alloc] init];
[parentViewController presentModalViewController:vc animated:YES];
}
#end
Then in each view controller import the ApplicationHelper and call the showMyModalView method
[ApplicationHelper showMyModalView:me];
This allows you to keep all the view handling code in a separate file to your application delegate.
Don't try and pass the reference around.
Just alloc] init]; a fresh instance where-ever you need to use it.
For example.
MyModalViewController *controller = [[MyModalViewController alloc] init];
[self presentModalViewController:controller animated:YES];
You can create one UIViewController and implement some delegate method for it. Then you can present the view controller like this:
[currentViewController presentViewController:yourViewController animated:YES];
And when an event is fired in your view controller, it will delegate to the caller.
In this case, you write the code only one time for "YourViewController", then reuse it where ever you want. You can also use pushviewcontroller also:
[self.navigationController pushviewcontroller:yourViewController animated:YES];

Access method in viewcontroller from appdelegate

I want to use appdelegate for applicationDidBecomeActive and I want this function to use method which is placed in viewcontroller. How I am gonna do that?
The only thing that I find is to access from anywhere the appdelegate.
You need to give your applicationDelegate class a reference to the viewController that you want to call the method on. You could do this by creating an instance variable or a property of the applicationDelegate that points to your viewController that you want to be able to call the method on. If you create your viewController in the init method of your appDelegate, or in your applicationDidLoad: method, then you can simply assign this viewController to the instance variable/property that you've created.
You can access the root view controller of your app from within the app delegate through the window property, that is self.window.rootViewController. The view controller that you want to access must be a child of the root view controller or at least accessible through it.
I had the same issue of needing to call a method on my view controller from the app delegate. After some digging and reading this answer I tried to call a method (saveData was the method in question) in my view controller directly from the app delegate and it worked as required.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {[self.window addSubview:rootViewController_iPad.view];
[self.window makeKeyAndVisible];
return YES;
}
-(void)applicationWillResignActive:(UIApplication *)application {
[rootViewController_iPad saveData];
}
Hope this helps.

Iphone access a property value from AppDelegate

How to access a property value of AppDelegate class from someView Controller without creating reference of the delegate in view controller?
I'm not quite sure what you mean - there are multiple ways to get information from your application delegate into a view controller, and the phrase "without creating reference of the delegate" is unclear. Your options basically are:
Reference the application delegate, casting as appropriate. You would write code in your view controller class like: id propertyValue = [(MyAppDelegate *)[[UIApplication sharedApplication] delegate] myProperty];
Pass the property in when creating the view controller. This requires the view controller to have a #property declared and #synthesized for use, then you would have the app delegate just set the property on the view controller instance.
Neither of these options require that you retain a copy of your app's delegate as a #property, but the first does reference the delegate once.
[UIApplication sharedApplication].delegate
You'll also need to include the app delegate header file in your view controller and possibly typecast the delegate from id to your actual app delegate class.
#include "MyAppDelegate.h"
((MyAppDelegate *)[UIApplication sharedApplication].delegate).myProperty;
[UIApplication sharedApplication].delegate;

How to access one UIViewControllers properties from another UIViewController?

I have one single MainViewController which has of course it's one main UIView. I have this main view comprised of many different subviews.
Some of these subviews have their very own ViewController.
Lets say the MAIN view (whose delegate is primarily MainViewController) has a container which loads another UIView that uses a separate UIViewController- SecondaryViewController as the delegate for most it's actions.
This container view is of course loaded in MainViewController via
MyContainerViewController *myContainerController =
[[MyContainerViewController alloc] ...];
[self addSubView: myContainerController.view];
the controller for myContainerController.view though is MyContainerViewController. How inside this controller do I access MainViewController properties? Specifically I need to access MainViewController's - self.navigationController property to push a new ViewController? :)
Does this make any sense? I assume there's going to be casting of some sort involved since it seems I need to somehow retain a reference to MainViewController inside SecondaryViewController?
It doesn't make sense to push a new ViewController from the SecondaryViewController in the MainViewController.
This screws up the design of the code. A child object will access its parents method to call a method. By other words: bad code.
Make a delegate call from the SecondaryViewController to the MainViewController that it state has changed. Then the MainViewController can decide to do with the call and the SecondaryViewController will not know anything about the implementation of the MainViewController.
So:
Make a protocol in SecondaryViewController.
Let the MainViewController be SecondaryViewController's delegate.
Implement the delegate method in MainViewController which pushes the new ViewController.
Expose the desired sub-view controllers as properties of the view controller that contains them.
Expose your root view controller(s) as properties of your app delegate, and synthesize them also.
When you want to access a different UIViewController, first obtain a reference to your appDelegate:
MyAppDelegate* myAppDelegate = [[UIApplication sharedApplication] delegate];
Then just use your chain of properties to get access to your desired view controller.
SubSubViewController* ssvc = myAppDelegate.rootViewController.subViewController.subSubViewController;
Some folks frown upon the use of the sharedApplication class method to obtain the reference to a delegate, but I've used it in multiple apps and not suffered for it (yet). The alternative is to pipe your appDelegate through your hierarchy of viewControllers.

Pass a Variable Up the Navigation Stack? - iPhone

I am able to pass a variable forward from view controller to view controller by pushing its view controller onto the navigation stack. An example of how I do it would be this:
MyViewController *controller = [[MyViewController alloc] initWithNibName:#"MyViewController" bundle:nil];
controller.myString = stringToPass;
[self.navigationController pushViewController:controller animated:YES];
[controller release];
However, what do I do if I want to pass a variable BACK UP the navigation stack? Using popViewControllerAnimated rather than pushViewController does not pass the variable up like I thought it would.
I need to be able to access the variable several pops up from the view controller it is defined in.
Any help will be greatly appreciated :)
You're passing values, not variables.
A view controller should not be responsible for popping itself. With Apple's view controllers (e.g. UIImagePicker), it is the parent view controller's responsibility to do the popping; the parent VC can also obtain the current value. (Not entirely correct; it might access the value before a keyboard autocompletion is applied)
Alternatively, if it's a value that can be shared globally, you can store it in your application delegate.
You can get a hold of the navigation controller in the VC stack using self.navigationController. You can just call some method like
[self.navigationController setMyString:stringToPassUp];
There are several more ways, e.g. self.tabBarController for the tabbarcontroller up in the stack, or most simply
[self.parentViewController setMyString:stringToPassUp];
edit given the downvotes on the examples above, and nobody giving a better explanation, let's discuss the proper way to do this.
If you have some object (like your MyViewController *controller) and that object has something to tell you, the usual approach is this:
MyViewController gets a delegate property, of type (id)
the view controller instantiating the MyViewController, sets this delegate property, like so:
controller.delegate = self;
MyViewController will, when it has something to say, do something like:
[self.delegate delegateMessage:arg1]; to "pass the message up" as you put it.
To do it perfectly, you may want to create your own #protocol MyViewControllerDelegate, and declare the class which would be setting controller.delegate = self; to adopt this protocol, by putting <MyViewControllerDelegate> on the #interface line. The delegate property of MyViewController should then be declared id<MyViewControllerDelegate> delegate;, so that the [self.delegate ...] messages can be matched to the protocol specification.
Basically the whole Cocoa Touch API works like this. Just have a look around for ideas how to implement your interaction.