1

I have a UILabel in interface builder that I've connected to a property, but it's staying nil through the viewDidLoad on that view controller. I've been stepping through and as soon as the DetailViewController is initialized, the label property is there but it is nil and it never seems to be initialized.

It was working until I switched from using segues to doing pushViewController on the navigation controller.

// DetailsViewController.h

#import <UIKit/UIKit.h>
#import "TLitem.h"

@interface DetailsViewController : UIViewController

@property (nonatomic, strong) TLitem *entry;
@property (weak, nonatomic) IBOutlet UILabel *entryLabel;

@end

Then in a table view in another view controller:

// EntryListViewController.m

DetailsViewController *details = [[DetailsViewController alloc] init];
[details setEntry:entry];
[self.navigationController pushViewController:details animated:YES];

And in the viewDidLoad:

// DetailsViewController.m
- (void)viewDidLoad {
    [super viewDidLoad];
    [self.view setBackgroundColor:[UIColor yellowColor]];
    TLitem *entry = [self entry];
    UILabel *label = [self entryLabel];

    label.text = [entry valueForKey:@"text"];
alsoALion
  • 449
  • 1
  • 5
  • 17
  • You mention you changed from segues to programmatically pushing your view controller. Show us the code where you instantiate it. – Nicolas Miari Sep 16 '15 at 02:17
  • If your view controller's view and the label in question are defined in a storyboard, you should instantiate it form the `UIStoryboard` instance. – Nicolas Miari Sep 16 '15 at 02:18
  • Instantiate the view controller? It's the first line in NewEntryListViewController.m, above. – alsoALion Sep 16 '15 at 02:18
  • Sorry, missed that. But as I thought, the answer below by Jeffrey Thomas should solve your problem. – Nicolas Miari Sep 16 '15 at 02:19

1 Answers1

4

[[DetailsViewController alloc] init] is not loading the view controller from the storyboard. It creates a new DetailsViewController, but nothing from IB will be connected. Look into -instantiateViewControllerWithIdentifier:

It will look something like

DetailsViewController *details = [self.storyboard instantiateViewControllerWithIdentifier:@"Some Storyboard Identifier You Create"];
details.entry = entry;
[self.navigationController pushViewController:details animated:YES];
Jeffery Thomas
  • 42,202
  • 8
  • 92
  • 117
  • This. all the info pertaining to outlet connections, etc. is in the storyboard. Storyboard-based view controllers are instantiated with `-initWithCoder:`. – Nicolas Miari Sep 16 '15 at 02:20
  • Thank you! self.storyboard is nil, and says it's a read-only property. Is there somewhere to set the storyboard for the whole app? (Edit - pressed enter too early). – alsoALion Sep 16 '15 at 02:34
  • @thisAnneM No. Every view controller must be created with the storyboard of it's creator (or `+storyboardWithName:`). How id you instantiate `NewEntryListViewController`? – Jeffery Thomas Sep 16 '15 at 02:40
  • @JefferyThomas (I updated the filename - it is actually EntryListViewController). `EntryListTableViewController *entryList = [[EntryListTableViewController alloc] init];` That file had no IBOutlets, which is why I got away with it. It in turn is created by the initial view controller. So do I refer to the Main Storyboard file in the initial view controller and then use `+storyboardWithName` each time I instantiate a new view controller? – alsoALion Sep 16 '15 at 02:45
  • @JefferyThomas - I changed that to `EntryListTableViewController *entryList = [self.storyboard instantiateViewControllerWithIdentifier:@"EntryList"]` so each successive view is instantiated with the storyboard and that fixed everything. Thanks so much :) – alsoALion Sep 16 '15 at 02:50