2010-04-19 4 views
21

Не удается получить правильные оценки для моего приложения iPad при его запуске в ландшафтном режиме. У меня есть соответствующие ключи, установленные в моем файле Info.plist, и мои диспетчеры представлений запускаются правильно в ландшафтном (и портретном, natch).UIScreen applicationFrame возвращает неправильный прямоугольник при запуске ландшафтного приложения (iPhone/iPad)

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

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

+16

Могу я просто сказать «неправильный» с этого момента? – jbrennan

ответ

6

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

+0

Итак, после того, как сообщение будет отправлено на контроллер просмотра для поворота, будет ли система координат отражать новую ориентацию? Например, после отправки сообщения ширина> высота? –

5

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

+0

Не могли бы вы объяснить, почему это спроектировано таким образом (или, по крайней мере, спекулировать). Мне кажется нелогичным давать неверные оценки экрана, если он был повернут. «Контроль» - это окно моего приложения (и я попытался использовать его фрейм, а также те же результаты). – jbrennan

+0

Причина в том, что окна можно поворачивать независимо от экрана. Пример: когда приложение для портрета запускает видеоролик YouTube, главное окно остается портретом, но над ним анимируется ландшафтное окно. Во время анимации, следует ли считать устройство портретным или альбомным? (ориентация акселерометра отделена от ориентации окна отдельно от ориентации панели состояния) – rpetrich

+0

Я тоже это заметил, это действительно странно. Спасибо за головы. – Justin

35

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

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

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

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

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

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

Почему не UIScreen

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

+0

Это так важно! Спасибо – coco

+0

Это очень полезно! Если бы я нашел это раньше, я бы сэкономил много времени! Благодаря! – coder284

6

Это путь я получаю правильный 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); 
0

я попал в такой же проблемой, когда отклоняя вид с dismissViewControllerAnimated в Кордове плагин. Я изменил код 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]; 
} 
14
CGRect bounds = [[UIScreen mainScreen] bounds]; // portrait bounds 
if (UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation])) { 
    bounds.size = CGSizeMake(bounds.size.height, bounds.size.width); 
} 
1

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

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

Here is the spot that taught me after a quick search Я не видел этого ответа выше, полагал, что это было бы полезно кому-то.

S

2

[[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]; ...