UIViewController -viewDidLoad не вызывается

Будучи новичком в Какао, у меня есть несколько проблем с Interface Builder, UIViewController и друзья.

у меня есть UIViewController подкласс с UIView определенный в xib, и с выходом вида контроллера, связанным с представлением. "Владелец файла" XIB установлен как подкласс myViewcontroller.

В этом случае следующий код для загрузки контроллера / представления (из контроллера основного представления) не работает должным образом:

if ( self.myViewController == nil )
{
    self.myViewController = [[MyViewController alloc]
        initWithNibName:@"MyViewController" bundle:nil];
}

[self.navigationController 
    pushViewController:self.myViewController animated:YES];

В методах MyViewController я разместил точки останова и регистрировал сообщения, чтобы увидеть, что происходит:

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

    if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
        NSLog(@"initWithNibName\n");
    }

    return self;
}

-(void)viewDidLoad {

    [super viewDidLoad];
    NSLog(@"viewDidLoad\n");
}

Ожидаемый результат

И то и другое -initWithNibName а также -viewDidLoad методы вызываются, и отображается представление myViewController.

Наблюдаемый результат

Только -initWithNibName называется, вид не отображается.

Я что-то пропустил? Кто-нибудь может порекомендовать что-нибудь проверить? (Особенно в удивительно непрозрачном инструменте Interface Builder).

11 ответов

Решение

Хорошо, у меня есть частичный ответ - может быть, гуру могут объяснить еще немного. Проблема в:

[self.navigationController pushViewController:myViewController animated:YES];

Если присмотреться, в этом случае self.navigationController это ноль - так что push-сообщение не идет никуда.

Вместо этого, если я отправлю:

[self.view addSubview:self.myViewController.view];

Затем появляется вид и -viewDidLoad называется.

Я не совсем уверен, почему self.navigationController не установлен в этом случае - единственное, что я могу думать о том, что self это подкласс UIViewController скорее, чем UITableViewController (где pushViewController Код пришел).

Кроме того, молчаливое разрешение отправлять сообщения на ноль кажется плохой идеей, хотя эти ответы говорят об обратном. Смотрите также мой вопрос здесь.

Окончательное редактирование:

Ответы в комментариях ниже, я понял, что функция отображения, за которой я фактически следовал (учитывая, что myViewController является модальным):

[self presentModalViewController:myViewController animated:YES];

Спасибо всем за полезные ответы.

RE: РЕШЕНИЕ НАЙДЕНО!!!!!

Действительно, это кажется рабочим решением, однако реальная уловка не в том, чтобы view.hidden свойство NO, что делает загрузку представления из nib-файла вызовом UIViewController's Метод view, вид фактически загружается из пера только тогда, когда метод view вызывается впервые.

В этом смысле простой [viewController view] сообщение заставит представление загрузить из файла пера.

РЕШЕНИЕ НАЙДЕНО!!!!!

Даже что-то столь безобидное, как это делает viewDidLoad вызов метода происходит.

Вставьте это сразу после выделения initWithNibName

viewController.view.hidden = NO; //calls viewDidLoad

Убедитесь, что выход представления в "Владельце файла" (ваш подкласс viewController) подключен к фактическому представлению (т. е. холсту 480X320, который вы видите на экране и используете для создания пользовательского интерфейса).

Просто использовать

- (void)viewDidAppear:(BOOL)animated{ 
        [super viewDidAppear:animated];
        //Your Code here
  }

вместо метода viewDidLoad.

Скорее всего, вы не связали предполагаемое ViewController в main.storyboard от Identity Inspector к обычаю class Вы создали Вы можете быть в состоянии перейти к этому контроллеру с других контроллеров представления через сегменты, но любой из viewDidLoad(), viewWillAppear() и т.д. не будут выполнены.

Еще одна причина, несколько очевидная в ретроспективе: если viewController.view устанавливается в коде, тогда событие viewDidLoad не сработает.

Это похоже на проблему с капитализацией для меня. Вы ссылаетесь на класс MyViewController вместо собственности myViewController в вызове pushViewController.

Проверьте журнал выполнения на наличие ошибок. Почти наверняка, NIB не загружается, и должна быть ошибка на этот счет. Наиболее вероятной причиной этого является невозможность положить его в комплекте. Посмотрите на этапе сборки "Копирование ресурсов" и убедитесь, что XIB действительно копируется. Выполните сборку для симулятора, зайдите в каталог сборки и убедитесь, что NIB находится в комплекте.app.

Помимо других ответов здесь,

Это часто случается, когда идентификатор, с которым вы создаете экземпляр ViewController из раскадровки, неверен. Например,

[[self getStoryboard] instantiateViewControllerWithIdentifier:MyVC];

Если MyVC - это идентификатор какого-либо другого ViewController, такое может случиться.

OP использует nibвместо раскадровки здесь. Но ответ применим.

Страница была представлена, но не видна в иерархии представления отладки и в устройстве (также в симуляторе), проблема возникает на основе, и я нашел исправление:

      func viewWillLayoutSubviews{
     if day == true{
            self.view.backgroundColor = .clear
     }else{
            self.view.backgroundColor = .blue
     }
}

Не пытайтесь реализовать self.view (представление viewcontrollers) в функции layoutsubviews. Так что лучше используйте self.view в viewwillappear или viewdidload. Эта проблема возникает начиная с устройств v-14.

Надеюсь, это сработает и для вас.

Другие вопросы по тегам