Eloy
Eloy

Reputation: 119

NSString from other UIViewController is null

Could anyone please explain to me why this isn't working? I think it is a real simple problem, but for some reason I am not getting it.

My problem: I have a NSString in my firstViewController with value "Hello!". Now I want to display this value in my secondViewController but the output is null.

This is my NSLog

2013-03-09  foo[95381:c07] value of foo in BITfirstViewcontroller: Hello!
2013-03-09  foo[95381:c07] value of foo in BITsecondViewcontroller: (null)

BITAppDelegate.m

#import "BITAppDelegate.h"
#import "BITfirstViewController.h"

@implementation BITAppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.

    BITfirstViewController *fvc = [[BITfirstViewController alloc]init];

    // Create navigationController and set InputViewController as root for navController
    UINavigationController *navController = [[UINavigationController alloc]initWithRootViewController:fvc];

    [self.window setRootViewController:navController];

    self.window.backgroundColor = [UIColor whiteColor];
    [self.window makeKeyAndVisible];
    return YES;
}

BITfirstViewController.h

#import <UIKit/UIKit.h>

@interface BITfirstViewController : UIViewController

@property (strong, nonatomic) NSString *foo;

-(IBAction)showSecondView:(id)sender;


@end

BITfirstViewController.m

#import "BITfirstViewController.h"
#import "BITsecondViewController.h"

@interface BITfirstViewController ()

@end

@implementation BITfirstViewController

@synthesize foo;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
        foo = [NSString stringWithFormat:@"Hello!"];
        NSLog(@"value of foo in BITfirstViewcontroller: %@",foo);

    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    [button addTarget:self
               action:@selector(showSecondView:)
     forControlEvents:UIControlEventTouchDown];
    [button setTitle:@"Show View" forState:UIControlStateNormal];
    button.frame = CGRectMake(80.0, 210.0, 160.0, 40.0);
    [self.view addSubview:button];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

-(IBAction)showSecondView:(id)sender;
{

    BITsecondViewController *svc = [[BITsecondViewController alloc]init];
    [self.navigationController pushViewController:svc animated:YES];
}

@end

BITsecondViewController.h

#import <UIKit/UIKit.h>


@class BITfirstViewController;

@interface BITsecondViewController : UIViewController

@property (nonatomic, retain) BITfirstViewController *fvc;

@end

BITsecondViewController.m

#import "BITsecondViewController.h"
#import "BITfirstViewController.h"

@interface BITsecondViewController ()

@end

@implementation BITsecondViewController

@synthesize fvc;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization

    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    NSLog(@"value of foo in BITsecondViewcontroller: %@", fvc.foo);

}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

Upvotes: 1

Views: 246

Answers (1)

Jeff Wolski
Jeff Wolski

Reputation: 6372

Try this in BITfirstViewController.m

-(IBAction)showSecondView:(id)sender;
{

    BITsecondViewController *svc = [[BITsecondViewController alloc]init];
    svc.fvc = self;  // you need to set this property as you prepare the svc
    [self.navigationController pushViewController:svc animated:YES];
}

EDIT:

Your fvc and svc are encapsulated, and don't have direct knowledge about each-other except though the use of properties (at least that's the way we try to do things in OOP). So, you were correct in creating a @property in your svc that allowed you to have a handle to your fvc, but [[BITsecondViewController alloc]init] will simply initialize that pointer to nil. Then you need to set that property to point to the intended object, which in this case is the fvc. Since the svc is being build from inside an instance of BITFirstViewController, the correct handle to pass in is self.

Upvotes: 2

Related Questions