Search code examples
objective-cinitviewdidloadaddsubview

calling addSubview in initWithNibName: causes viewDidLoad (and other UI Object inits)to fire before the addSubview Call executes


I'm adding a button in the middle of my initWithNibName:bundle:, when i add the button view to self.view, the view goes to start to initialize before it add's the button. So the Code in viewDidLoad gets fires before the initWithNibName:bundle: is finished. There is code below the addSubview that is relied on in the viewDidLoad and causes it to crash/not work since the init code has not run.

I've had the same experience when I added the button code to the viewDidLoad method. There is a UITableView in the .xib and the table gets inited before the rest of the viewDidLoad gets run and caused the tableView to get bad Data.

What is the best practice for adding a view to a view when you are initing and loading the view? just put all the addSubViews before the Return?

Thanks!

Here is my initWithNibName:bundle:

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil{

    self = [super initWithNibName:nibNameOrNil bundle:nil];

    [self setIoUIDebug:(IoUIDebugSelectorNames)];

    if (IoUIDebug & IoUIDebugSelectorNames) {
        NSLog(@"%@ - %@", [self description], NSStringFromSelector(_cmd) );
    }   

    CGRect frame = CGRectMake(20, 521, 500, 37);                                


    saveButton = [UIButton newButtonWithTitle:NSLocalizedStringFromTable(@"Save Animation Label",@"ScreenEditor",@"Save Animation Label")
                                       target:self
                                     selector:@selector(saveButtonPressedAction:)
                                        frame:frame
                                        image:[UIImage imageNamed:@"BlueButtonSmall.png"]
                                 imagePressed:[UIImage imageNamed:@"BlueButtonSmallPressed.png"]
                                darkTextColor:NO];                      

    [self.view addSubview:saveButton];  // <- Right here I'll hit breakpoints in other parts of viewDidLoad and cellForRowAtIndexPath, before the lined below get executed. 
    [saveButton setEnabled: NO];
    [saveButton setUserInteractionEnabled: NO];

    newAnimation = nil;
    selectedSysCDAnimation = nil;
    selectedIoCDTag = nil;
    animationSaved = NO;  
    return self;
}

Solution

  • You should add the subviews inside viewDidLoad this will mean that the views are added when the main view is loaded into memory. I would reserve your initWithNibName:bundle: call for custom initialization and not interacting with the UI as this what viewDidLoad is designed for.

    In regards to your tableView, you should put a call to load the tables datasource inside of viewDidLoad. Once the datasource is loaded, you can simply call reloadData on the tableview to load the data into the tableview.

    For Example:

    - (void)viewDidLoad
    {
    
        [super viewDidLoad];
    
        [self.view addSubview:saveButton];
    
        [self loadDataSource];
    
    }
    
    - (void)loadDataSource {
    
      // load datasource here
    
      [self.tableView reloadData];
    
    }