4

I have masterViewController and detailViewController. Masterview pushes detailView. When going back to masteViewController I want to update the foo value. But I only get NULL from nslog. How can I set the parenteViewContrller.foo value to @"bar" when navigationback?

masterViewController.h

    NSString *foo; 
    -(void)setFoo:(NSString *)fooValue
    @property(nonatomic, retain) NSString *foo; 

masterViewController.m

@synthesize foo;

-(void)setFoo:(NSString *)fooValue{

    NSLog(@"updated foo:%@", fooValue);
}

detailViewController.m

-(void)goBack{
    [self.navigationController.parentViewController setValue:@"bar" forKey:@"foo"];
    [self.navigationController popViewControllerAnimated:YES];
}
Zoe
  • 27,060
  • 21
  • 118
  • 148

5 Answers5

6

[UIViewController parentViewController] will not return what you are expecting from iOS 5 onward, instead you should be using [UIViewController presentingViewController]

If you are just targeting iOS 5, it is easy enough to start using presentingViewController instead, but if not I would advise that you manually pass your UIViewController on:

// DetailViewController.h

@class MasterViewController;

@interface DetailViewController : UIViewController

@property (assign, nonatomic) MasterViewController *masterViewController;

@end


// DetailViewController.m

#import "DetailViewController.h"
#import "MasterViewController.h"

@implementation DetailViewController

- (void)goBack {

    [self.masterViewController setFoo:@"bar"];

    // dismiss this view controller
}

@end


// MasterViewController.h

@interface MasterViewController : UIViewController

- (void)setFoo:(NSString *)bar;

@end


// MasterViewController.m

#import "MasterViewController.h"
#import "DetailViewController.h"

@implementation MasterViewController

- (void)goForward {

    DetailViewController *detailViewController = ...;
    [detailViewController setMasterViewController:self];

    // present this view controller
}

@end
Ell Neal
  • 6,014
  • 2
  • 29
  • 54
  • Would you suggest saving the UIVIewController in AppDelegate for a global solution? – Dejell Dec 27 '12 at 12:55
  • @Odelya I would always advise that you avoid clogging up your app delegate with application-wide variables. Better to use singleton instances or some form of manager class. – Ell Neal Dec 28 '12 at 01:05
0

In order for setValue:ForKey: to work, your view controller must conform to NSKeyValueCoding protocol.

Try this:

-(void)goBack{
    [self.navigationController.parentViewController setFoo:@"bar"];
    [self.navigationController popViewControllerAnimated:YES];
}

and don't forget to retain/release appropriately in your setFoo: method. You probably also need to type cast parentViewController to avoid any warnings.

0xSina
  • 20,973
  • 34
  • 136
  • 253
  • This won't work in iOS 5, `[UIViewController parentViewController]` has a different meaning in iOS 5 so you should use `[UIViewController presentingViewController]` if this is the case. – Ell Neal Feb 20 '12 at 11:16
0

Pass the reference of the master with assign property to detail view. Using this reference set the foo value before performing pop action.

Apurv
  • 17,116
  • 8
  • 51
  • 67
0

gIf you want to pass a object to the parent you could try creating an external object in a header file and importing the header in the controller where you want to use it however THIS IS NOT BEST PRACTICE but it's a quick fix import

extern MyObject* Object;
@interface GlobalVariables : NSObject {

}

@end

All you have to do now is include the header in the controllers and use the global variable.

If you want to do it by the books i suggest you create a delegate that handles the object passing.

Radu
  • 3,434
  • 4
  • 27
  • 38
0

Normally, under this scenario, you need to use delegate. Check out my answer to this similar question in this SO.

Community
  • 1
  • 1
user523234
  • 14,323
  • 10
  • 62
  • 102