UIViewController, созданный с помощью initWithNibName:пучок:или через IBOutlet вести себя по-другому

StackOverflow https://stackoverflow.com/questions/2257124

Вопрос

Я обнаружил странное поведение и хотел бы, чтобы мне объяснили, какое неверное утверждение я делаю.

В классе AppDelegate только что созданного проекта WindowBased я добавляю в окно UIViewController.
Я могу сделать это двумя разными способами:
- с помощью IBOutlet.В IB я просто создал экземпляр UIViewController, установил для него класс TestViewController и подключил его (сценарий A кода).
— создание UIViewController с кодом (сценарий Б).

    - (void)applicationDidFinishLaunching:(UIApplication *)application {    

#define USE_IBOUTLET YES // Comment this line to switch to scenario B

#ifdef USE_IBOUTLET
    // Scenario A

    [window addSubview:theTestViewController.view];
    [window makeKeyAndVisible];
#endif


#ifndef USE_IBOUTLET
    // Scenario B

    TestViewController *theTestViewControllerProgrammatically;

    theTestViewControllerProgrammatically = [[TestViewController alloc] initWithNibName:nil bundle:nil];

    // According to Apple: "It is a good idea to set the view's frame before adding it to a window.", so let's do it
    [theTestViewControllerProgrammatically.view setFrame:[[UIScreen mainScreen] applicationFrame]];

    [window addSubview:theTestViewControllerProgrammatically.view];

    [window makeKeyAndVisible];
#endif
}

Поскольку я не настраивал объект в IB, у меня должно быть одинаковое поведение в обоих сценариях.

Сценарий А: использование IBOutlet работает должным образом.
Но сценарий Б имеет следующие проблемы:
- Изображение находится в неправильном положении (20 пикселей выше и закрыто строкой состояния).
- Размер представления не изменяется должным образом (например, попробуйте переключить строку состояния вызова).

Почему?

ZIP-архив проекта здесь, если вы хотите воспроизвести проблему: http://dl.dropbox.com/u/1899122/code/ProtoWindowBasedStrangeness.zip

Это было полезно?

Решение

После моих многословных ответов это прозвучит очень глупо, но проблему, с которой вы столкнулись, легко исправить (программно).

Эта строка:

[theTestViewController.view setFrame:[[UIScreen mainScreen] applicationFrame]];

На самом деле должно быть:

[theTestViewControllerProgrammaticaly setFrame:[[UIScreen mainScreen] applicationFrame]];

Вы устанавливали фрейм для VC, установленный IB, а не тот, который вы создали программно.

В любом случае - стоит отметить, что все мои комментарии по-прежнему актуальны!Есть еще несколько вещей, которые вам придется сделать программно, если вы не используете объекты контроллера IB (например, настройка элементов панели навигации).

Павел

Другие советы

У меня возникла проблема, очень похожая на вашу: я заметил, что не все объекты VC созданы равными!Проблема, с которой я столкнулся, заключается в настройке элементов панели навигации, я просто не могу этого сделать, когда File's Owner является объектом контроллера представления, экземпляр которого я создаю программно.Это работает, только если я разархивирую объекты контроллера IB.

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

Я считаю, что Apple создала в IB объекты контроллеров, которые немного более специализированы.Одно из предположений, что это может быть правдой, заключается в том, что у объектов IB VC есть атрибут, который вы можете установить, который не имеет прямого соответствующего свойства для класса UIViewController, который я вижу, поэтому объекты контроллера IB могут иметь некоторые дополнительные функции, которые не могут быть подклассами UIViewController, отличными от IB. извлекать выгоду.Учитывая, что объекты в .xib являются полными «лиофилизированными» объектами, Apple, возможно, включила все виды частных атрибутов, которые мы не можем видеть или использовать в их версиях IB — это может иметь некоторое влияние на то, как инициализируются объекты. .

Например, в вашем MainWindow.xib, выберите объект IB VC, и вы сможете установить для него атрибуты из палитры инспектора, например «Изменить размер представления из NIB».Если вы снимите этот флажок и перезапустите приложение, вы увидите, что виртуальный виртуальный компьютер выглядит точно так же, как в сценарии B.Поскольку вы не можете проверить этот элемент из атрибутов владельца файла (даже если он является UIViewController), вы не можете воспользоваться тем, что делает контроллер представления, чтобы обеспечить желаемое поведение.

Результатом этого является то, что при использовании TestViewController.xib для инициализации вашего объекта VC в коде ни один из специфических для IB атрибутов VC не установлен, поэтому создается стандартный UIViewController, и поэтому такие вещи, как атрибут «Изменить размер представления из NIB» и настройка элементов навигации, должны быть реализовал сам.

Я еще не нашел способа воспользоваться преимуществами функциональности контроллеров представлений IB, когда я создаю их экземпляры с помощью initWithNibName:bundle:nibBundle (Я предполагаю, что это все личные вещи, к которым у нас нет доступа), но, надеюсь, это могло дать вам отправную точку...

Конечно, я могу быть совершенно не прав и кто-то выставит меня полным идиотом!

Павел

Вероятно, в случае B это представление не знает о наличии строки состояния.Вам необходимо соответствующим образом изменить его размер и отрегулировать его положение, чтобы учесть строку состояния.Это делается путем изменения свойств фрейма (размера) и границ (расположения) UIView.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top