UIViewController изменяет размер между viewWillAppear и viewDidAppear?

У меня очень странная ошибка в моем проекте. У меня есть UIScrollView как мой основной, большой взгляд. Внутри него у меня есть UIViewController (не UITableViewController), который имеет переменную экземпляра UITableView, а также некоторые разные UIButtons. Я установил рамку представления контроллера вида CGRectMake(0, 64, 320, 388), так как над ним есть панель вкладок (пока это еще не работает). Сначала он отлично работает и отлично выглядит, но как только я представляю и увольняю modalViewController (таким образом, перезагружая UIViewController, я полагаю), он подталкивает представление UIViewController в начало экрана (по умолчанию он устанавливает CGRectMake(0, 0, 320, 460), но поскольку я установил wantsFullScreenLayout в NO, он теперь устанавливает его в CGRectMake(0, 0, 320, 388).

Я проследил эту проблему где-то между viewWillAppear и viewDidAppear. Вот мои точные журналы после отклонения modalViewController:

2011-05-06 11: 08: 39.974 Кампус [1570: 207] Рама 0.000000, 64.000000, 320.000000, 388.000000 (viewWillAppear)
2011-05-06 11: 08: 40.378 Кампус [1570: 207] Рама 0.000000, 0.000000, 320.000000, 388.000000 (viewDidAppear)

Как вы можете видеть, кадр отлично в viewWillAppear, но не в viewDidAppear.

Я попытался исправить следующее:
- Установите нужный кадр в loadView, viewDidLoad, viewWillAppear и viewDidAppear.
- Установите для меня wantsFullScreenLayout значение NO.
- Убиты мои вызовы [super viewWillAppear:] и [super viewDidAppear:] в моем переопределении метода.

Что мне делать?!?!?

Ответ 1

Моя проблема заключалась в том, что с iOS 4 Apple поддерживала только 1 контроллер просмотра для каждого окна. Однако с iOS 5 Apple добавила поддержку контроллеров контейнерных представлений и добавила методы для UIViewController, таких как addChildViewController:. Алгоритм контроллера контейнера решил мою проблему. Для получения дополнительной информации посетите Справочник класса UIViewController.

EDIT: для тех, кто из вас слишком ленив, чтобы искать "контроллер контейнера" в ссылке на класс, здесь суть связанного раздела в ссылке на класс:

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

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

Контроллер просмотра контейнера должен связывать контроллер детского представления с собой перед добавлением корневого представления childs в иерархию представлений. Это позволяет iOS правильно маршрутизировать события в контроллеры детского просмотра и взгляды, которыми управляют эти контроллеры. Аналогично, после удаления childs root из его иерархии представлений, он должен отключить это контроллер детского представления от себя. Чтобы сделать или разбить эти ассоциации, ваш контейнер вызывает определенные методы, определенные базовый класс. Эти методы не предназначены для вызова клиентами ваш контейнерный класс; они должны использоваться только вашими контейнерами для обеспечения ожидаемого поведения сдерживания.