Как правильно определить ориентацию интерфейса при запуске? - PullRequest
6 голосов
/ 21 ноября 2010

[Вопрос обновлен]

Так вот в чем проблема, я наконец сузил ее до этого. Если вы создаете новый UIViewController во всех методах

- (id)init;
- (void)loadView;
- (void)viewDidAppear:(BOOL)animated;
- (void)viewDidLoad;
(...)

Стандартным интерфейсомOrientation является Portrait, и если обнаружен альбомный режим, он быстро повернется к этой ориентации. Который затем может быть обнаружен с помощью:

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation;

Проблема в том, что на iPad довольно сложно подготовить интерфейс для текущей ориентации интерфейса в пределах loadView (или одного из других), поскольку он будет возвращать только Portrait. Это приведет к нескольким проблемам:

1) Я хочу, чтобы мой контент перезагружался в режиме портрета, но НЕ в альбомном режиме. Обычно я бы поместил оператор if в loadView. Если в портретном режиме, перезагрузите контент. Но в этом случае он всегда возвращает портрет и, следовательно, всегда загружает контент.

2) Я хочу использовать метод presentPopoverFromRect: inView: enabledArrowDirections: animated: - в режиме портрета, чтобы автоматически отображать всплывающее меню при запуске приложения. Это приведет к сбою приложения при запуске в портретном режиме. Причина: «Поповерс не может быть представлен из вида, у которого нет окна».

Единственное безопасное предположение находится внутри 'didRotateFromInterfaceOrientation: (UIInterfaceOrientation) fromInterfaceOrientation', но этот метод не будет запущен, если он запускается в портретном режиме.

// ----

Обновление (15,37)

'UIApplicationWillChangeStatusBarOrientationNotification'

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

if (UIDeviceOrientationIsPortrait(interfaceOrientation)) {
    // layout subviews for portrait mode
} else {
    // layout subviews for landscape mode
}

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

Ответы [ 3 ]

8 голосов
/ 22 ноября 2010

Попробуйте [[UIApplication sharedApplication] statusBarOrientation].

6 голосов
/ 22 ноября 2010

Правильный способ - запросить у устройства его ориентацию, поскольку технически вид не имеет ориентации.;)

Так что вы правильно используете UIDevice.Из документации видно, что сначала вам нужно сгенерировать уведомления об ориентации устройства, прежде чем эта информация верна.Тогда он будет работать как нужно.

UIDevice *myDevice = [UIDevice currentDevice];
[myDevice beginGeneratingDeviceOrientationNotifications];
UIDeviceOrientation currentOrientation = [myDevice orientation];
[myDevice endGeneratingDeviceOrientationNotifications];

Примечание: Это дает вам текущую ориентацию устройства.Если текущий видимый / вид сверху контроллер не разрешил поворот в эту ориентацию, тем не менее вы получите текущую ориентацию устройства, а не ту, которую использует в данный момент самый верхний контроллер вида.


Редактировать после того, как вопрос был обновлен:

Вы правы, что ориентация для самого верхнего контроллера вида (работала правильно для контроллеров подпредставления) всегда возвращает 1 (то есть UIInterfaceOrientationPortrait) в loadView.Однако сразу после этого будет вызван метод willRotateToInterfaceOrientation:duration:, и указанная здесь ориентация будет правильной, поэтому вы сможете использовать этот метод.

- (void) willRotateToInterfaceOrientation:(UIInterfaceOrientation)toIfaceOrient
                                 duration:(NSTimeInterval)duration
1 голос
/ 22 ноября 2010

Я не уверен, что это действительно решит мою проблему, но, просмотрев документацию, я обнаружил следующее:

typedef enum {
   UIInterfaceOrientationPortrait           = UIDeviceOrientationPortrait,
   UIInterfaceOrientationPortraitUpsideDown = UIDeviceOrientationPortraitUpsideDown,
   UIInterfaceOrientationLandscapeLeft      = UIDeviceOrientationLandscapeRight,
   UIInterfaceOrientationLandscapeRight     = UIDeviceOrientationLandscapeLeft
} UIInterfaceOrientation;

и

typedef enum {
   UIDeviceOrientationUnknown,
   UIDeviceOrientationPortrait,
   UIDeviceOrientationPortraitUpsideDown,
   UIDeviceOrientationLandscapeLeft,
   UIDeviceOrientationLandscapeRight,
   UIDeviceOrientationFaceUp,
   UIDeviceOrientationFaceDown
} UIDeviceOrientation;

Таким образом, поскольку FaceUp и FaceDown были добавлены, смотреть на ориентацию устройства бессмысленно по причинам интерфейса. Поэтому теоретически @MarkAdams справедливо отмечает, что в этом случае для ориентации интерфейса следует использовать [[UIApplication sharedApplication] statusBarOrientation].

Или, конечно, UIViewController имеет опцию 'interfaceOrientation'.

...