1

I have a Container View that holds 1 of 3 view controllers swapped out by 3 tabs (across the bottom).

Here's my Storyboard:

enter image description here

I'm taking this approach so that I can have custom tabs and a single Save button for all the fields in this big form.

How can I access the IBOutlets in those 3 child view controllers from inside my Entry Detail View Controller class?

Here's what I've done to try and access it in the parent.

//EntryFlightInfoViewController.h (Child 1)
@property (strong, nonatomic) IBOutlet UITextField *aircraftIdTextField;

Then in my parent class (Entry Detail View Controller) I can't access the property:

//EntryDetailViewController.m (Parent)
#import "PPEntryFlightInfoViewController.h"

- (IBAction)buttonSave:(id)sender {
  NSLog(@"save: %@", _aircraftIdTextField); //(!) Error: Use of undeclared identifier '_aircraftIdTextField'
}

How do I access another view controller's IBOutlets when they are in a Container View? Hopefully I'm on the right track. Forgive me as I'm still quite new to Objective-C. :)

Clifton Labrum
  • 13,053
  • 9
  • 65
  • 128
  • Having controllers know about the workings of it's children seems funky to me. I would have a separate object (NSManageObject, NSDictionary, etc), that holds all the values for your detail entry. ; Aircraft Id, Instruments, signature, etc. Then when you load the detail entry sub view controllers, I would pass in that object. The sub view controllers would then update the values in that object. – NixonsBack May 14 '13 at 04:25

4 Answers4

2

View controllers in a container view are children of the controller with the container view. So, you can access the current child view controller with self.childViewControllers[0], and the outlet with [self.childViewControllers[0] aircraftIdTextField]

rdelmar
  • 103,982
  • 12
  • 207
  • 218
  • I see nothing wrong with this approach for container views. Why jump through the hoops used in some of the other answers? – mbeaty Mar 05 '15 at 23:24
1

Clifton, whenever you can, you should avoid having VCs know about each others' controls. You could just have the save button send out a message, and have the three subordinate VCs observe for it. When they get the message, they save their info. That way, the master VC doesn't have to know about controls inside its subordinates.

user2379765
  • 161
  • 3
  • I assume you're referring to NSNotification. Is that correct? I've never used it. So if I wire this up, will each view controller retain the values in its own UITextFields even if they aren't presently loaded into the container view? The tabs toggle one of three view controllers. – Clifton Labrum May 14 '13 at 02:34
1

The short answer is you can't unless you write your own communication layer. You can get at the different views via the childViewControllers (mentioned above) as well as getting your own custom pointers in your prepareForSegue method call as the view is loaded into the container view. (see this link for more info on this) This will work great if you are forcing the user to visit each page. If not then the same defaults you'd load there on the first viewDidLoad can likely be saved without checking the specific view controller.

Apple's answer is to never have a save button. If you edit it, you meant it, and it's saved immediately. =)

That said, were I you, I'd have an object that all of the views access to load/unload their data for storage whenever you show/hide the different views, possibly in viewDidLoad/viewDidDisappear. This way you always have a "known good" object ready for saving, and you won't have to directly access those view controllers.

Hope that helps some.

slycrel
  • 4,275
  • 2
  • 30
  • 30
  • After further research, I have come to the same conclusion you have introduced. I need to save each child view's fields in an `NSManagedObjectContext` (I'm using Magical Record and Core Data). On `viewDidDisappear` I'll just save all the fields into the object, then save to the database when the user hits Save. Thanks! – Clifton Labrum May 14 '13 at 18:34
  • You bet. I found this question via the FB page for Utah mobile developers, glad I could help out. =) – slycrel May 14 '13 at 20:41
0

You need a reference to the current tab view controller, then you ask it for the outlet:

self.entryFlightInfoViewController.aircraftIdTextField

By trying to use _aircraftIdTextField your trying to directly access an instance variable on the container view controller class. Obviously if doesn't have a variable with that name so you get the compile error.

Wain
  • 118,658
  • 15
  • 128
  • 151