UIScreen applicationFrame возвращает неправильный прямоугольник при запуске приложения в альбомной ориентации (iPhone / iPad) - PullRequest
21 голосов
/ 19 апреля 2010

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

В моем методе applicationDidFinishLaunching: я вызываю селектор после 3-секундной задержки, и этот метод вызывает [[UIScreen mainScreen] applicationFrame], но он возвращает мне портретную рамку (т.е. высота> ширина).

Кто-нибудь знает, как это исправить? Это пахнет для меня ошибкой (если так, я подам радар), но если это предполагаемое поведение, где это задокументировано?

Ответы [ 8 ]

35 голосов
/ 29 октября 2010

Я никогда не полагаюсь на [[UIScreen mainScreen] applicationFrame], особенно во время запуска приложения.

При создании представлений в коде используйте суперпредставление для установки кадра.

Если вы используете xibs с «симулированными элементами интерфейса», они будут иметь правильный размер и все будет отлично работать.

Приложения на основе UINavigationController

В случае приложения на основе UINavigationController возьмите фрейм непосредственно из self.navigationController.view, не пытайтесь использовать [self loadView] и self.view.superview. UINavigationController использует «скрытые» подпредставления для выполнения своей работы, поэтому прямое суперпредставление не будет работать.

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

Почему бы не UIScreen

[[UIScreen mainScreen] applicationFrame] не работает надежно (особенно при запуске приложения в альбомной ориентации). По моему опыту, свойство interfaceOrientation viewcontroller не будет соответствовать ориентации applicationFrame.

14 голосов
/ 11 февраля 2013
CGRect bounds = [[UIScreen mainScreen] bounds]; // portrait bounds
if (UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation])) {
    bounds.size = CGSizeMake(bounds.size.height, bounds.size.width);
}
6 голосов
/ 01 февраля 2012

Так я получаю правильный 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);
6 голосов
/ 20 апреля 2010

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

5 голосов
/ 19 апреля 2010

Это как задумано. Вы должны запросить размер вашего суперпредставления и скорректировать при необходимости.

2 голосов
/ 16 июня 2013

[[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]; ...
1 голос
/ 16 июня 2013

Итак, добавьте стартовый образ и присвойте ему суффикс -568h, согласно указаниям Apple.

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

Вот место, которое научило меня после быстрого поиска Я не видел этот ответ выше, подумал, что это будет кому-то полезно.

S

0 голосов
/ 11 октября 2012

У меня возникла такая же проблема при закрытии представления с помощью dismissViewControllerAnimated в плагине Cordova. Я изменил код 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];
}
...