Получение ориентации устройства перед вращением или принудительное включение при запуске. Есть идеи? - PullRequest
0 голосов
/ 28 октября 2009

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

 if (orient == UIInterfaceOrientationPortrait || orient == 0){ 
  r = CGRectMake(0.0, 0.0, 320.0, 480.0);
        // draw stuff
    } else {
  r = CGRectMake(0.0, 0.0, 480.0, 320.0);
        // draw stuff
    }

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

Мои вопросы: могу ли я как-то получить правильную ориентацию в такой ситуации? Жаль, что это не может быть воспроизведено в симуляторе, поэтому я не уверен, что код, который я вставил, ответственен за эту ошибку, но это место, где я исправляю рамки вида в соответствии с ориентацией. Может быть, есть другой (правильный) способ сделать это? И, может быть, я могу заставить приложение работать в портретном режиме, пока не сработает событие поворота?

Ответы [ 2 ]

1 голос
/ 28 октября 2009

Я не думаю, что это ошибка. Когда iPhone сидит на столе, вся гравитация измеряется вдоль оси Z. Для определения ориентации устройства используются оси x-y, но ускорение не измеряется рядом с ними в вашем сценарии.

РЕДАКТИРОВАТЬ: Дополнительные пояснения:

Это изображение показывает, как Ось ориентирована на iPhone: альтернативный текст http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIAcceleration_Class/Art/device_axes.jpg

Поэтому, когда iPhone лежит на спине, ускорение -1g применяется к оси z. Чтобы получить измеренные ускорения, просто зарегистрируйте делегата, реализующего UIAccelerometerDelegate с общим экземпляром UIAccelerometer. Посмотрите пример AccelerometerGraph , как это сделать.

Чтобы определить, сидит ли iphone на столе, сделайте что-то вроде этого:

- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration
    {

    // lowPass filter first

    // now choose orientation
      if (fabs([acceleration z]) >= 0.9) // sitting on the table: choose new mode or lock current mode
      if (fabs([acceleration y]) >= 0.9) // probably portrait mode
      if (fabs([acceleration x]) >= 0.9) // probably landscape mode

    }

Точность акселерометра составляет 18mG = 0.018G, поэтому примите это во внимание. Также вам необходимо изолировать себя от эффектов мгновенных изменений движения, простой фильтр LowPass идеально подходит для этого. Пример AccelerometerGraph показывает, как реализовать такой фильтр.

Также выберите очень низкий updateInterval, если вам не нужна большая точность, 30 Гц должно подойти для ваших целей.

1 голос
/ 28 октября 2009

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

...