Почему мне нужно вручную установить кадр моего представления в viewDidLoad?

У меня довольно простая настройка с помощью UINavigationController внутри UITabBarController. Я хочу программно отобразить представление rootViewController этого навигатора, но когда я смотрю на self.view.frame внутри viewDidLoad, я получаю это (например, в ландшафте ):

1. view frame: {{20, 0}, {748, 1024}} // looks like an odd portrait mode 

Затем я авторотирую портрет, и я получаю следующее:

 2. view frame: {{0, 0}, {768, 911}} 

Затем, когда я возвращаюсь к Landscape, рамка теперь выглядит так:

 3. view frame: {{0, 0}, {1024, 655}} 

И другие события авторотации будут триггером между значениями фрейма # 2 и # 3.

Чтобы обойти странность №1, я сейчас делаю это в viewDidLoad:

 if (UIInterfaceOrientationIsPortrait(self.interfaceOrientation)) { self.view.frame = CGRectMake(0, 0, 768, 911); } else { self.view.frame = CGRectMake(0, 0, 1024, 655); } 

Я чувствую, что здесь явно что-то отсутствует. Почему рамка по умолчанию представления не соответствует кадру, когда он авторотирует обратно в одну и ту же ориентацию? Не отображается ли рамка представления исходной ориентации? Очень смущенный…

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

Что я делаю не так?

ОБНОВЛЕНИЕ: при отключении всех объектов автосохранения в результате изменения результат # 1 будет выглядеть следующим образом:

 view frame: {{0, 0}, {748, 1024}} 

Это кажется немного ближе, но все же не соответствует №3.

    Рамка не гарантируется, что она будет одинаковой в viewDidLoad, поскольку она будет отображаться в конечном итоге. UIKit настраивает кадр представления вашего controllerа представления перед его отображением на основе контекста, в котором будет отображаться. Размер определяется на основе ориентации интерфейса и размеров любой видимой панели навигации, панели вкладок, панели инструментов или строки состояния (которая сама имеет высоту, которая может меняться, например, когда вы находитесь на телефонном звонке).

    Это помогает понять, что происходит при загрузке и отображении представления controllerа представления:

    1. Что-то в первый раз обращается к свойству представления controllerа view . Это может произойти в вашем собственном коде или в UIKit в ответ на действие пользователя, например, выбор вкладки.

    2. UIKit lazy загружает представление controllerа вашего представления, вызывая loadView если он определен, или загружая представление из NIB, которое было указано в initWithNibName:bundle: Если не существует, UIKit просто загружает пустой вид.

    3. UIKit вызывает viewDidLoad после полной загрузки представления и его viewDidLoad . На этом этапе кадр представления будет таким, каким он был установлен в NIB, или в loadView .

    4. Что-то требует, чтобы UIKit отображал вид controllerа вашего вида. Опять же, это может быть действие пользователя, например, нажатие на вкладке или явный вызов метода в вашем коде, например pushViewController:animated: или presentModalViewController:animated:

    5. UIKit изменяет размер представления на основе контекста, в котором он будет представлен, как описано выше.

    6. UIKit вызывает viewWillAppear: Теперь рамка должна быть размером, который будет отображаться. (?) EDIT: Это может быть больше недействительным. См. Комментарии ниже.

    7. UIKit отображает представление с анимацией или без нее.

    8. UIKit вызывает viewDidAppear:

    Как вы можете видеть, если вам нужно знать размер frameworks вашего представления до его представления, viewWillAppear: это ваша единственная возможность. Просто помните, что этот размер может измениться после появления представления по различным причинам, включая события поворота или изменения высоты строки состояния. По этой причине очень важно дать каждому подзапрос подходящую маску autoresizingMask, чтобы гарантировать, что макет может правильно настроиться для любого изменения границ.

    Если вы хотите создать свою иерархию представлений вручную, рекомендуемое место для этого – в loadView. Поскольку вы сами создаете представление в этом методе, вы можете инициализировать его фрейм, как хотите. Размер, который вы выбираете, не имеет большого значения, так как UIKit, скорее всего, изменит его на вас. Просто убедитесь, что вы правильно настроили свои авторезистентные макеты.

    В вашем classе будет метод

     - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { // Return YES for supported orientations return YES; } 

    Поместите кадр в этот метод … Тогда он будет работать нормально.

    Например:

     - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { // Return YES for supported orientations if(interfaceOrientation == UIDeviceOrientationPortrait || UIDeviceOrientationPortraitUpsideDown) self.view.frame = CGRectMake(0, 0, FRAME.WIDTHinPOTRAIT, FRAME.HEIGHTinPOTRAIT); else if(interfaceOrientation == UIDeviceOrientationLandscapeRight || UIDeviceOrientationLandscapeLeft) self.view.frame = CGRectMake(0, 0, FRAME.WIDTHinLANDSCAPE, FRAME.HEIGHTinLANDSCAPE); return YES; } 

    FRAME.WIDTH> желаемая ширина FRAME.HEIGHT> желаемая высота

    Interesting Posts

    Wix Взаимодействие с условиями, свойствами и пользовательскими действиями

    Windows эквивалентна cron?

    Что означает этот код C # со «стрелкой» и как он называется?

    Оберните выбор вокруг … в Блокноте ++

    Рубин на рельсах. Как использовать метод Active Record .build в: относится к отношениям?

    Какая польза от слова вместо

    Почему добавление нового значения в список перезаписывает предыдущие значения в списке

    Использование NSString в операторе switch

    Как включить / отключить аппаратное обеспечение из командной строки Windows 7

    Может ли HTML5 взаимодействовать с периферийными устройствами, такими как сканеры и считыватели кредитных карт?

    Нужно ли отменить подписку на наблюдаемые, созданные методами Http?

    Выключение программного обеспечения не работает в Windows 8

    Исключение ResultSet – до начала набора результатов

    Итерация по интерфейсу

    Как определить, поддерживает ли Android PDF?

    Давайте будем гением компьютера.