2009-05-27 5 views
27

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

У меня есть подкласс 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).

+0

Связанный вопрос: http://stackoverflow.com/questions/1479576/viewdidload-not-called-in-subclassed-uiviewcontroller – Casebash

+4

у вас возникли проблемы с друзьями? – Marty

ответ

12

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

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

Присмотревшись, в этом случае self.navigationController равна нуль - поэтому толкающее сообщение не будет не-где.

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

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

Тогда представление появляется и -viewDidLoad называется.

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

Кроме того, молчание, позволяющее сообщениям идти в ноль, кажется плохой идеей, хотя these answers сказать иначе. См. Также мой вопрос here.

Заключительный изменить:

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

[self presentModalViewController:myViewController animated:YES]; 

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

+4

Не берите безмолвное сообщение-к-нолю, вы будете использовать его все время, когда привыкаете к нему :-) Это, безусловно, может быть загадочным, когда вы впервые начинаете. Что касается того, почему navigationController равен нулю: инициализируется ли он как контроллер корневого представления UINavigationController? Если нет, вы не можете использовать pushViewController, пока не сделаете это! –

+1

Я думаю, что у Адама это точно здесь, убедитесь, что ваш взгляд правильно помещен в стек навигации, прежде чем пытаться получить его navigationController. –

4

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

+0

Да, спасибо, это, безусловно, дело. Я упомянул об этом выше, но просто дважды проверял. – Justicle

4

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

+0

Плохо, что это была только опечатка при перемещении кода в stackoverflow - теперь я исправляю вопрос. Благодарю. – Justicle

2

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

+0

Все хорошие моменты, вызывается CompileXIB, а MyViewController находится на этапе копирования ресурсов и появляется в пакете приложений. Проверял это несколько раз с чистой сборкой. Также я изменил -initWithNibName NSLog, чтобы написать «self», с результатом: «initWithNibName self = », поэтому он выглядит как загружаемый. – Justicle

+1

initWithNibName: bundle: не загружает NIB. Первый вызов -view загружает NIB (поэтому проверка self ничего не доказывает). Убедитесь, что self.naviagationController не равен нулю. Если бы это было так, вы никогда не загрузили бы NIB. Кроме того, вы, вероятно, протекаете в своем назначении self.myViewController (предполагая, что это свойство «сохранить», которое должно быть). Вам нужно автообновить его. Престижность в использовании аксессуаров там. В какао, когда «ничего не происходит», что-то нет.Самый распространенный случай - вы не подключили его к IB. –

+0

Ах спасибо, Роб, не видел твой комментарий там - проблема была в том, что self.navigationController был ноль. Не знаю, почему (см. Мой ответ ниже). – Justicle

8

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

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

Вставьте это право после того, как Alloc initWithNibName

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

, потому что каждый раз, когда вы используете свойство view, getter и/или setter запускают загрузку представления. даже просто набрав «self.view»; было бы достаточно enoguh – hfossli

+0

Но делать это, вероятно, не рекомендуется, так как это замыкает всю ленивую схему загрузки. – tomwhipple

26

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

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

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

+1

Лучший ответ. [viewController view] <- Это то, что помогает ответить на вопрос оп. Вот как -viewDidLoad вызывается по требованию. – denicio

+1

Ты спас мой день. Большое спасибо. – Rendel

+1

Отличный ответ !!! но значения не присваиваются метке и ползунку в Xib – Sanju

5

Просто используйте

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

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

1

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

5

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

 Смежные вопросы

  • Нет связанных вопросов^_^