4

I suspect this is a very simple answer or I'm on totally the wrong track. I need to be able to set variables and access fields etc in a view controller from either App Delegate or another view controller.

Previously I could do this from App Delegate to my first view controller by doing the following in 'didFinishLaunchingWithOptions':

viewController = (ViewController *)self.window.rootViewController;

After that I could/can access methods within the view controller from App Delegate by doing the normal [viewController someMethod];.

If I have multiple view controllers (currently have 3), how can I access the other ones from other locations? Incidentally I have found SOME explanations but all talk about nib/xibs combined with code. I don't have them, I have a storyboard and code (I'm new to app dev).

Thanks!

Richard Williams
  • 337
  • 1
  • 5
  • 12

1 Answers1

5

In your appDelegate you can simply declare properties that will hold references to this viewControllers.

For example:

in AppDelegate.h

@property (nonatomic, strong) UIViewController *vc1;
@property (nonatomic, strong) UIViewController *vc2;

in AppDelegate.m

@synthesize vc1,vc2;

Wherever you are creating this viewControllers you can access your appDelegate and set it's properties to hold the right reference. Don't forget to include AppDelegate.h to this file.

UIViewController *someVC = [init view controller....];
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
appDelegate.vc1 = someVC;

And from then on you can access this viewController as appDelegate's property.

EDIT: for storyBoarding it looks like this would be safe to do in - (void)viewDidLoad.

Or an even better approach would be (as Richard mentioned) to do this in - (id)initWithCoder:(NSCoder *)decoder

"When instantiating a view controller from a storyboard, iOS initializes the new view controller by calling its initWithCoder: method instead." from documentation

But please note, if you're changing any data from one view controller to another you might want to consider holding this data in a separate part of code (so called model in model-view-controller approach). This would be the safest way to 'exchange' data between viewControllers.

Rok Jarc
  • 18,765
  • 9
  • 69
  • 124
  • Thanks for the answer, I think I need one extra piece of information. I do not init my View Controllers programmatically, it's handled by the Story Board... how do I init them and hook them up with the SB? – Richard Williams Mar 13 '12 at 20:13
  • Actually forget that, I'm with you now... setup the variable in App Delegate and then set it's value from the VC back to App Delegate. Thanks will give it a go. – Richard Williams Mar 13 '12 at 20:15
  • @RichardWilliams: ok, just 'ring' if you run into problems :) – Rok Jarc Mar 13 '12 at 20:17
  • Can you tell me where you would set the variable in AD from the VC? Inside 'viewDidLoad'? Is there a method that is called earlier than 'viewDidLoad'? Thanks again! – Richard Williams Mar 13 '12 at 20:18
  • @RichardWilliams: yes, it looks viewDidLoad is suitable. – Rok Jarc Mar 13 '12 at 20:32
  • 1
    Aha... -(id)initWithCoder:(NSCoder *)aDecoder seems to get called :) – Richard Williams Mar 13 '12 at 20:33
  • @rokjarc isn't it too heavy to store the UIViewController in AppDelegate? – Dejell Dec 27 '12 at 12:57
  • Depends on complexity of the app. But AppDelegate usually holds reference to rootViewController (at least). Other viewControllers can be properties of rootViewController - if you subclass it. In this case appDelegate holds 'heavier' rootViewController - not much difference then. Don't confuse this with holding all the data (ie: model) in appDelegate: that is simply wrong. – Rok Jarc Dec 27 '12 at 13:20