Высота и ширина на iPhone (/ iPad) - PullRequest
8 голосов
/ 19 октября 2010

Это всего лишь тестовое приложение. Существует только класс AppDelegate, чтобы создать все, что я сделал, - это создал приложение на основе окна, установил в качестве поддерживаемых ориентаций только ландшафт в info.plist, а затем добавил следующий код:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    
[application setStatusBarOrientation:UIInterfaceOrientationLandscapeLeft];

// Override point for customization after application launch.
UIAlertView *test = [[UIAlertView alloc] initWithTitle:@"hu" message:@"hui" delegate:nil cancelButtonTitle:@"hi" otherButtonTitles:nil];
[test show];
[window makeKeyAndVisible];
    NSLog(@"win %f - %f", window.bounds.size.width, window.bounds.size.height);
return YES;
}

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

В любом случае, журнал все еще дает это:

win 768.000000 - 1024.000000

Это неправильный путь (и поэтому, когда я добавляю подпредставления в моем реальном приложении, кадры не правильные)

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

Я дам 500 репутации (это все, кроме10 моей репутации) человеку, который хотя бы может объяснить, почему это происходит, и, надеюсь, найти решение.

Ответы [ 7 ]

17 голосов
/ 23 октября 2010

Мне кажется, «Запуск в ландшафтном режиме» из Руководства по программированию приложений для iOS в основном объясняет, что происходит с вашим тестовым приложением:

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

  • В файле Info.plist вашего приложения добавьте UIInterfaceOrientationключ и установите его значение в ландшафтном режиме.Для альбомной ориентации вы можете установить значение этого ключа в UIInterfaceOrientationLandscapeLeft или UIInterfaceOrientationLandscapeRight.

  • Разместите ваши представления в ландшафтном режиме и убедитесь, что их параметры автоматического изменения размера установлены правильно.

  • Переопределить контроллер вашего представления mustAutorotateToInterfaceOrientation: метод и вернуть YES только для желаемой альбомной ориентации и NO для портретной ориентации.

Важно: В предыдущих шагах предполагается, что ваше приложение использует контроллеры представлений для управления своей иерархией представлений.Контроллеры представлений предоставляют значительный объем инфраструктуры для обработки изменений ориентации, а также других сложных событий, связанных с представлениями.Если ваше приложение не использует контроллеры вида - как это может быть в случае с играми и другими приложениями на основе OpenGL ES - вы отвечаете за поворот поверхности рисования (или настройку команд рисования) по мере необходимости, чтобы представить свой контент в альбомном режиме.

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

В первом абзаце я прочитал, что приложения для iOS всегда запускаются в портретном режиме, а затем контроллер корневого представления поворачивает свое представление, чтобы соответствовать ориентации устройства немедленно и без анимации после добавления в окно.Это означает, что само UIWindow не вращается, поэтому его размеры всегда будут в терминах портретной ориентации (как сказал tadej5553).Кроме того, кадры всех подпредставлений UIWindow также будут с точки зрения портретной ориентации (поскольку рамка всегда определяется в координатах родительского представления).Таким образом, независимо от того, как вы поворачиваете устройство, рамка контроллера корневого представления всегда будет в плане портретной ориентации.Однако, поскольку свойство границ вида определяется в терминах его собственных координат, эта высота и ширина должны отражать текущую ориентацию вида.

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

10 голосов
/ 22 октября 2010

UIWindow ничего не знает о ротации. Методы вращения инкапсулированы в UIViewController. (автоматическое вращение и т. д.)

UIAlertView использует свойство statusBarOrientation UIApplication для выбора ориентации оповещения.

// Rotate to a specific orientation.  This only rotates the status bar and updates the statusBarOrientation property.
// This does not change automatically if the device changes orientation.
@property(nonatomic) UIInterfaceOrientation statusBarOrientation;

Как видно из заголовков SDK, statusBarOrientation не изменяется автоматически. Поэтому либо вы, либо UIViewController (автоматическое вращение) должны изменить это свойство.

Если вы запустите портрет (что соответствует ориентации по умолчанию в UIWindow) и используете shouldAutorotateToInterfaceOrientation и разрешите UIViewController обрабатывать поворот, это изменит statusBarOrientation UIApplication при каждом изменении ориентации устройства.

Но если вы запускаете в ландшафтном режиме, вам следует вручную установить statusBarOrientation на один раз.

Надеюсь, это поможет.

6 голосов
/ 26 октября 2010

Использовать границы представления

4 голосов
/ 20 октября 2010

Окно всегда будет давать размер для портретной ориентации.Всегда.

Но вид на нем даст правильные измерения (относительно ориентации), поэтому обязательно используйте их.

3 голосов
/ 28 октября 2010

Вот что я сделал, чтобы заставить это работать:

  • В Info.plist убедитесь, что у вас есть следующие параметры:
    • Начальная ориентация интерфейса = Пейзаж (правая домашняя кнопка)
    • Поддерживаемые ориентации интерфейса
      • Элемент 0 = Пейзаж (правая домашняя кнопка)
      • Элемент 1 = Пейзаж (левая домашняя кнопка)
  • Добавить основанный на xib контроллер представления с представлением в нем, которое автоматически изменяет размеры (устраняет проблему изменения размера и т. Д.)
    • Примечание. Я использовал здесь навигационный контроллер с контроллером представления, потому что это то, что мне пригодилось, но я думаю, что это должно работать и с одним VC.

Добавьте немного кода вашему делегату приложения:

_rootViewController = [[RootViewController alloc] initWithNibName:@"RootViewController" bundle:nil]; 
_navigationController = [[UINavigationController alloc] initWithRootViewController:self.launcherViewController];
[window addSubview:self.navigationController.view]; //I think this is the key.
[window makeKeyAndVisible];

Я думаю, что ключ - это вид, я пробовал его без него, и на iPhone он работал просто отлично, на iPad, хотя, как вы говорите, предупреждение показывалось в портретном режиме. Когда я добавил вид назад, предупреждение отображается в альбомном режиме по желанию.

3 голосов
/ 19 октября 2010

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

Ручная установка ориентации строки состояния является своего рода «низким уровнем». Ваши контроллеры представления также должны возвращать UIInterfaceOrientationLandscapeLeft в методе экземпляра shouldAutorotateToInterfaceOrientation.

0 голосов
/ 21 февраля 2011

У меня не было ничего, кроме проблем с жестким кодированием моего приложения в режиме «Только ландшафт».В большинстве случаев визуальных проблем не было, но кнопки в нижних 20 пикселях не могли быть выбраны.Я сделал clipToBounds на своем основном UIWindow и добавил границу на его слой, и я увидел, что UIWindow находится под строкой состояния.Я попытался изменить смещение x моего UIWindow на 20 (UIWindow по-прежнему в Portrait, его содержимое - Landscape), но это означало, что мои UIControllers были смещены вниз на 20 пикселей (не знаю почему).Хотя эта проблема отличается от вашей, я также обнаружил ту же проблему, что и у вас, в том, что границы и рамки при печати выглядят правильными.

В любом случае, чтобы сократить длинный рассказ, я изменил свой plist с UIInterfaceOrientationLandscapeLeft наUIInterfaceOrientationLandscapeRight, а также изменил мой метод UIViewController на:

-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 
{
  return (interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}

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

Дайте мне знать, если это решит вашу проблему

...