UIViewController -viewDidLoad не вызывается
Будучи новым для Cocoa, у меня есть несколько проблем с 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
, представление не отображается.
Я что-то пропустил? Может кто-нибудь порекомендовать что-нибудь проверить? (В частности, в удивительно непрозрачном инструменте интерфейса Builder).
Ответы
Ответ 1
Хорошо, у меня есть частичный ответ - возможно, гуру могут объяснить еще кое-что. Проблема заключается в следующем:
[self.navigationController pushViewController:myViewController animated:YES];
Более внимательно, в этом случае self.navigationController
равно nil - поэтому push-сообщение не идет туда-сюда.
Вместо этого, если я отправлю:
[self.view addSubview:self.myViewController.view];
Затем появится представление и вызывается -viewDidLoad
.
Я не совсем уверен, почему self.navigationController
не задан в этом экземпляре - единственное, о чем я могу думать, это то, что self
является подклассом UIViewController
, а не UITableViewController
(где pushViewController
код пришел).
Кроме того, молчание, позволяющее сообщениям переходить в нуль, кажется плохой идеей, хотя эти ответы говорят иначе. См. Также мой вопрос here.
Окончательное редактирование:
Ответы в комментариях ниже, я понял, что функция отображения, которая была на самом деле после (с учетом того, что myViewController является модальной):
[self presentModalViewController:myViewController animated:YES];
Спасибо всем за их полезные ответы.
Ответ 2
RE: РЕШЕНИЕ НАЙДЕТ!!!!!
Действительно, это кажется рабочим решением, однако реальный трюк заключается не в установке свойства view.hidden
в значение NO, что делает загрузку представления из файла nib вызовом метода просмотра UIViewController's
, представление только фактически загружается из наконечника при первом вызове метода view.
В этом смысле простое сообщение [viewController view]
заставит представление загрузиться из файла nib.
Ответ 3
РЕШЕНИЕ НАЙДЕНО!!!!!
Даже такое безобидное, как это делает вызов метода viewDidLoad
.
Вставьте это право после выделения initWithNibName
viewController.view.hidden = NO; //calls viewDidLoad
Ответ 4
Просто используйте
- (void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
//Your Code here
}
вместо метода viewDidLoad.
Ответ 5
Скорее всего, вы могли бы не связать предполагаемый ViewController
в main.storyboard
с Identity Inspector
с пользовательским class
, который вы создали. Возможно, вы сможете перейти к этому контроллеру с других контроллеров представления через segues, но любые из viewDidLoad()
, viewWillAppear()
и т.д. Не будут выполнены.
Ответ 6
убедитесь, что выходная точка представления в File Owner (ваш подкласс viewController) подключена к фактическому виду (т.е. холст 480X320, который вы видите на экране, который используется для создания пользовательского интерфейса)
Ответ 7
Мне кажется, что проблема с капитализацией. Вы ссылаетесь на класс MyViewController
вместо свойства MyViewController
в вызове pushViewController.
Ответ 8
Проверьте журнал выполнения ошибок. Почти наверняка, NIB не загружается, и в этом случае должна быть ошибка. Наиболее вероятной причиной этого является неспособность поместить его в комплект. Посмотрите в фазе сборки "Копирование ресурсов" и убедитесь, что XIB фактически копируется. Создайте симулятор и спуститесь в каталог сборки и убедитесь, что NIB находится в пакете .app.
Ответ 9
Другая причина, несколько очевидная в ретроспективе: если viewController.view
установлен в код, тогда событие viewDidLoad не будет запускаться.