UIScreen applicationFrame возвращает неправильный прямоугольник при запуске ландшафтного приложения (iPhone/iPad)
Не удается получить правильные оценки для моего приложения iPad при его запуске в ландшафтном режиме. У меня есть соответствующие ключи, установленные в моем файле Info.plist, и мои диспетчеры представлений запускаются правильно в альбомной ориентации (и портрете, ночевка).
В моем методе applicationDidFinishLaunching:
я вызываю селектор после 3-секундной задержки, и этот метод вызывает вызов [[UIScreen mainScreen] applicationFrame]
, но возвращает мне портретный кадр (например, высотa > ширина).
Кто-нибудь знает, как это исправить? Это пахнет как ошибка для меня (если так я сделаю радар), но если это предназначено для поведения, где это задокументировано?
Ответы
Ответ 1
Когда вы держите iPad в альбомной ориентации и запускаете приложение, контроллер просмотра сначала видит границы для портретного вида (даже при том, что ориентация - это пейзаж). Затем диспетчер представлений получит сообщение для поворота в альбомную ориентацию до его появления.
Ответ 2
Я никогда не полагаюсь на [[UIScreen mainScreen] applicationFrame]
, особенно во время запуска приложения.
При создании представлений в коде используйте супервизор для установки фрейма.
Если вы используете xibs с "имитируемыми элементами интерфейса", они будут иметь нужный размер и все будет работать отлично.
Приложения на основе UINavigationController
В случае приложения на основе UINavigationController захватите кадр непосредственно из self.navigationController.view
, не пытайтесь использовать [self loadView]
и self.view.superview
. UINavigationController использует "скрытые" подпрограммы для выполнения этой задачи - поэтому прямой просмотр не будет работать.
UINavigationController является особенным, потому что во время запуска приложения контроллер навигации изменяет размеры ваших просмотров после вызова loadView
. Когда авторезистентные удары в вас заканчиваются небольшим отрывом в нижней части экрана.
Почему не UIScreen
[[UIScreen mainScreen] applicationFrame]
не работает надежно (особенно во время запуска приложения в ландшафте). Мой опыт в том, что свойство viewcontroller interfaceOrientation
не будет соответствовать ориентации applicationFrame
.
Ответ 3
CGRect bounds = [[UIScreen mainScreen] bounds]; // portrait bounds
if (UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation])) {
bounds.size = CGSizeMake(bounds.size.height, bounds.size.width);
}
Ответ 4
Так я получаю правильный CGRect, когда контроллер просмотра находится на пейзаже:
CGRect landscapeBounds;
if (self.view.frame.size.width < self.view.frame.size.height)
landscapeBounds = CGRectMake(self.view.frame.origin.y, self.view.frame.origin.x, self.view.frame.size.height, self.view.frame.size.width);
else
landscapeBounds = CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y, self.view.frame.size.width, self.view.frame.size.height);
Ответ 5
Это так же хорошо. Вы должны запросить размер своего супервизора и при необходимости отрегулировать.
Ответ 6
[[UIScreen mainScreen] applicationFrame]
всегда будет возвращать портретный прямоугольник, даже если приложение находится в ландшафтном режиме. Это связано с тем, что UIWindow
никогда не вращается, а просто меняет преобразование rootViewController.view
.
Чтобы убедиться, вы можете распечатать объект корневого представления в портретном и альбомном режимах, и вы увидите что-то вроде этого:
Портрет:
<UIView: 0x96290e0; frame = (0 20; 768 1004); ...
Пейзаж:
<UIView: 0x96290e0; frame = (0 20; 768 1004); transform = [0, 1, -1, 0, 0, 0]; ...
Ответ 7
Итак, добавьте изображение запуска и дайте ему суффикс -568h, согласно руководствам Apple.
Я не понимаю, почему кто-то со здоровым умом сделает настройку системы зависящей от графика; но я просто тестировал, и это сработало.
Вот место, которое научило меня после быстрого поиска Я не видел этого ответа выше, полагал, что это было бы полезно кому-то.
S
Ответ 8
У меня возникла такая же проблема, когда вы отклоняли представление с помощью rejectViewControllerAnimated в плагине Кордовы.
Я изменил код singingAtom для метода viewWillAppear в MainViewController, который изменил размер после отклонения модального представления:
- (void)viewWillAppear:(BOOL)animated
{
CGRect appFrame = [[UIScreen mainScreen] applicationFrame];
UIDeviceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
if (UIDeviceOrientationLandscapeLeft == orientation ||
UIDeviceOrientationLandscapeRight == orientation)
{
if (appFrame.size.width < appFrame.size.height)
{
appFrame = CGRectMake(appFrame.origin.y, appFrame.origin.x, appFrame.size.height, appFrame.size.width);
}
}
self.view.frame = appFrame;
[super viewWillAppear:animated];
}