вызов addSubview в initWithNibName: вызывает запуск viewDidLoad (и других объектов пользовательского интерфейса) до выполнения вызова addSubview.

Я добавляю кнопку в середине моего initWithNibName:bundle:, когда я добавляю представление кнопки в self.view, представление начинает инициализироваться до добавления кнопки. Таким образом, код в viewDidLoad срабатывает до завершения initWithNibName:bundle:. Под addSubview находится код, на который опирается viewDidLoad, и он вызывает сбой/не работает, поскольку код инициализации не запущен.

У меня был такой же опыт, когда я добавил код кнопки в метод viewDidLoad. В .xib есть UITableView, и таблица запускается до того, как запускается остальная часть viewDidLoad, что приводит к тому, что tableView получает неверные данные.

Каков наилучший способ добавления представления в представление при инициализации и загрузке представления? просто поместить все addSubViews перед возвратом?

Спасибо!

Вот мой 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;
}

person scooter133    schedule 17.10.2011    source источник


Ответы (2)


Вы должны добавить подпредставления внутрь viewDidLoad, это будет означать, что представления добавляются, когда основное представление загружается в память. Я бы зарезервировал ваш вызов initWithNibName:bundle: для пользовательской инициализации и не взаимодействовал с пользовательским интерфейсом, поскольку для этого предназначен viewDidLoad.

Что касается вашего tableView, вы должны поместить вызов для загрузки источника данных таблиц внутри viewDidLoad. Как только источник данных загружен, вы можете просто вызвать reloadData в табличном представлении, чтобы загрузить данные в табличное представление.

Например:

- (void)viewDidLoad
{

    [super viewDidLoad];

    [self.view addSubview:saveButton];

    [self loadDataSource];

}

- (void)loadDataSource {

  // load datasource here

  [self.tableView reloadData];

}
person Alex    schedule 17.10.2011
comment
Изначально у меня была похожая проблема, но я сузил ее до одного и того же. У меня был addSubView кнопки в ViewDidLoad, хотя в середине ViewDidLoad My IB TableView становился Init'ed. У моего ViewDidLoad был код инициализации для TableView, который не был установлен до того, как TableView был запущен. Итак, мой tableview cellForRowAtIndexPath не возвращал ячейку, потому что код инициализации в ViewDidLoad еще не был завершен. Поэтому я помещаю addSubView в конец ViewDidLoad, и это помогает, хотя хотелось бы знать, почему viewDidLoad прерывается для инициализации TableView. - person scooter133; 18.10.2011

Любой доступ к свойству представления контроллера представления будет лениво инициализировать представление. Это вызовет вызов viewDidLoad, который будет выполнен до того, как доступ к свойству представления вернется в initWithNibName:. Вы должны добавить дополнительное представление в viewDidLoad или с помощью построителя интерфейса.

person Brian Coleman    schedule 17.10.2011