Advertise here




Advertise here

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Sending messages back to the Root View Controller

rpstro02rpstro02 Posts: 256Registered Users
edited February 2011 in iPhone SDK Development
Hey guys,
This is probably a newb question but I'm stuck. In a the utility template (or flip view template) there is a root view controller and two other view controllers for the main views. The root view controller creates instances of the two main views and loads them with the nibs. My question is how do I pass information from a main view back to the root view? Or from one main view to the other? Can I create IBOutlets from nib file to nib file? Or what?

I want to have some options on a flip view and the primary application on the front.

Thanks.
Post edited by rpstro02 on

Replies

  • spjwebsterspjwebster Posts: 9New Users
    edited January 2009
    I had to do a similar thing with my TaxCalc application, though I wanted to pass notifications to a parent controller in a UINavigationController stack.

    As far as I know, you have two options. The first is to create a delegate protocol, much like many of the built-in UIKit classes, and have your one controller assign itself as the delegate for the other. You can then call the appropriate method of the delegate object when something changes. See Syntax for creating View delegate in Objective-C on Stack Overflow for a simple example of creating a delegate.

    However, you can only have one delegate at a time. If it's likely you're going to have multiple objects wanting to 'listen out' for changes, you're better of implementing a custom NSNotification. I'm not sure if this is the best approach, but here's what my code look:

    First, define a constant for the notification name. You don't strictly have to do this, but this way if you make a typo and get the notification name wrong you'll get a compile error rather than a silent failure.

    TaxYearPickerViewController.h
    #define kTaxYearChangeNotificationName	@"TaxYearChangeNotification"
    
    @interface TaxYearPickerViewController ...
    ...
    @end
    


    Then, at the appropriate point in your code, post the notification and include a link to the dispatching object and (if applicable, though in my case it isn't) any relevant data in an NSDictionary.

    TaxYearPickerViewController.m
    - (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
    	...
    	[[NSNotificationCenter defaultCenter] postNotificationName:kTaxYearChangeNotificationName object:self];
    }
    

    With that done, you just need to make one view controller listen out for the notifications of another via the NSNotificationCenter singleton. NSNotificationCenter gives you a few options for how targetted you want your listeners to be. In my case I only wanted kTaxYearChangeNotificationName notifications from a specific object, so I used this when creating my TaxYearPickerViewController instance:

    IncomeSummaryController.m
    [[NSNotificationCenter defaultCenter] 
        addObserver:self 
              selector:@selector(taxYearChanged:) 
                 name:kTaxYearChangeNotificationName 
                object:taxYearPickerController
    ];
    

    This will call the taxYearChanged: method of IncomeSummaryController whenever taxYearPickerController posts the kTaxYearChangeNotificationName notification.

    Hope this helps.

    Steve
  • skinnytronskinnytron Posts: 69Registered Users
    edited January 2009
    I have found that easiest way to handle this is to just pass a reference of your parent view controllers to your child view controllers.

    Here is an example of how it would look.

    ChildViewController.h
    @class RootViewController;
    
    @interface ChildViewController : UIViewController {
      RootViewController *rootViewController;
    }
    

    ChildViewController.m
    #import "RootViewController.h"
    
    @implementation ChildViewController
    
    @synthesize rootViewController;
    

    RootViewController.m
    ChildViewController *childViewController = [[ChildViewController alloc] initWithNibName:@"ChildView" bundle:nil];
    childViewController.rootViewController = self;
    

    This is a simple solution which hasn't presented any problems for me so far.
  • exorcyzeexorcyze Posts: 496Registered Users
    edited January 2009
    In the ChildViewController.h do you also need to have the following?
    @property (nonatomic, assign) RootViewController *rootViewController;
    

    Yet another option would be ( assuming that your RootViewController is the first item on your navigationController stack ) to get the app delegate ( MyAppDelegate *delegate = [[UIApplication sharedApplication] delegate]; ) and then you can use that to get the item at index 0 in the navigationController stack. You could then send messages directly to that controller without adding additional items.

    Though personally I would say out of all the approaches the NSNotificationCenter to broadcast messages is going to be the cleanest as it's the most decoupled. It also means it's easier to have multiple items in your app listen to particular messages rather than using a bucket-brigade approach to event bubbling. Just my $0.02.
    My Apps on AppStore : <a href="http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=301046713" target="_blank">gScale</a> (guitar scales reference), <a href="http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=302865690" target=
  • skinnytronskinnytron Posts: 69Registered Users
    edited January 2009
  • rpstro02rpstro02 Posts: 256Registered Users
    edited January 2009
    Interesting approaches. THis really helps me. Thanks guys!
  • fonixfonix Posts: 2New Users
    edited March 2010
    Thank you so much! I was banging my head against this for days, but your code did the trick!
    skinnytron wrote: »
    I have found that easiest way to handle this is to just pass a reference of your parent view controllers to your child view controllers.

    <edited for brevity>

    This is a simple solution which hasn't presented any problems for me so far.
  • mohan.agadkarmohan.agadkar Posts: 28Registered Users
    edited April 2010
  • tinymonkey1tinymonkey1 Posts: 13Registered Users
    edited June 2010
    skinnytron wrote: »
    I have found that easiest way to handle this is to just pass a reference of your parent view controllers to your child view controllers.

    Here is an example of how it would look.

    ..... Code here......

    Sorry for bumping this thread but you have just saved my life. Thank you skinnytron. You have NO IDEA how much this has helped me.:):)
  • CarlosTCarlosT Posts: 118New Users
    edited September 2010
    Sorry for bumping this thread but you have just saved my life. Thank you skinnytron. You have NO IDEA how much this has helped me.:):)

    Thank you! You have also saved my life. Been working on this for 3 days now!

    Cheers
    My App site <a href="http://thetappyappco.com/" target="_blank">http://thetappyappco.com/</a>;
  • mickeywilkomickeywilko Posts: 1New Users
    edited February 2011
    I'm struggling with this - should any methods in the parent view controller be accessible in the child's nib in IB?

    Many thanks.

    Mike.
Sign In or Register to comment.