2010-08-01 2 views
4

Я слушаю UIDeviceOrientationDidChangeNotification, чтобы настроить свой пользовательский интерфейс на основе ориентации устройства.Неточная ориентация устройства, возвращаемая UIDeviceOrientationDidChangeNotification

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

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

Любая помощь очень ценится.

Спасибо,

+0

Не могли бы вы поделиться кодом, который используете для ответа на уведомление? – nschum

ответ

3

Если вам интересна только ориентация вашего интерфейса (например, пейзаж или портретная ориентация устройства), вы НЕ должны использовать UIDevice: ориентация (или константы UIDeviceOrientation *, если хотите), а скорее используйте UIApplication: statusBarOrientation, который использует константы UIInterfaceOrientation *.

Я использую следующий код для проверки ландшафтном модуса:

static inline bool isOrientationIsLandscape() { 
    return UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation]); 
} 

И для портретной модуса:

static inline bool isOrientationIsPortrait() { 
    return UIInterfaceOrientationIsPortrait([[UIApplication sharedApplication] statusBarOrientation]); 
} 

Это стоило мне целое утро, чтобы выяснить, потому что нет UIDeviceOrientationFace [ Up | Down] на симуляторе, только на реальном устройстве. Так что мое приложение постоянно работало на симуляторе, но на самом устройстве у меня время от времени было какое-то неопределенное поведение во время тестирования.

Теперь он работает на самом устройстве, как на симуляторе.

HTH

1

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

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

9

Я нашел свою проблему.

В viewWillAppear у меня есть:

[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; 
    [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(didChangeOrientation:) name: UIDeviceOrientationDidChangeNotification object: 
    [UIDevice currentDevice]]; 

А вот обработчик уведомлений:

- (void) didChangeOrientation: (id)object { 
    UIInterfaceOrientation interfaceOrientation = [[object object] orientation]; 
    //DLog(@"val is %i", interfaceOrientation); 
    if (interfaceOrientation == UIDeviceOrientationLandscapeLeft || interfaceOrientation == UIDeviceOrientationLandscapeRight || interfaceOrientation == UIDeviceOrientationPortrait) { 
    [self orientInterface:interfaceOrientation]; 
} 

Проверив, что ориентация является одним из двух пейзажей или два портрета я не обращая внимания на UIDeviceOrientationFaceUp и UIDeviceOrientationFaceDown ориентации. Таким образом, настройка телефона в одной из этих двух ориентаций не повлияет на ориентацию моего интерфейса.

Моя проблема заключалась в том, что я не рассматривал faceUp и faceDown и обрабатывал их как в заявлении else, которое предполагало пейзаж.

Смежные вопросы