как определить ориентацию iPhone перед поворотом - PullRequest
12 голосов
/ 21 июля 2009

В моей программе я двигаю вещи, основанные на вращении, но я не вращаю весь вид. Я использую:

  static UIDeviceOrientation previousOrientation = UIDeviceOrientationPortrait;

 - (void)applicationDidFinishLaunching:(UIApplication *)application {   
    [window addSubview:viewController.view];
    [window makeKeyAndVisible];
    [[NSNotificationCenter defaultCenter] addObserver:self
           selector:@selector(didRotate:)
           name:@"UIDeviceOrientationDidChangeNotification" object:nil];

}

- (void) didRotate:(NSNotification *)notification{  
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];

    [self doRotationStuff:orientation: previousOrientation];
previousOrientation = orientation;

} 

Это работает до тех пор, пока при запуске программы ориентация устройства является книжной, но не если исходная ориентация является альбомной или перевернутой, потому что [self doRotationStuff] вносит изменения относительно отличия от предыдущей ориентации

Есть ли способ определения ориентации при запуске или непосредственно перед вращением устройства?

Ответы [ 7 ]

12 голосов
/ 09 января 2010

В зависимости от ваших обстоятельств, более простым вариантом может быть свойство interfaceOrientation класса UIViewController. Это правильно перед вращением.

3 голосов
/ 21 июля 2009

Обновлен:

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

#define kUpdateFrequency 30  // Hz
#define kUpdateCount 15 // So we init after half a second
#define kFilteringFactor (1.0f / kUpdateCount)

- (void)applicationDidFinishLaunching:(UIApplication *)app
{
    [UIAccelerometer sharedAccelerometer].updateInterval = (1.0 / kUpdateFrequency);
    [UIAccelerometer sharedAccelerometer].delegate = self;
    accelerometerCounter = 0;
    ...
}

- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)accel
{
    // Average out the first kUpdateCount readings
    // acceleration_[xyz] are ivars typed float
    acceleration_x = (float)accel.x * kFilteringFactor + acceleration_x * (1.0f - kFilteringFactor);
    acceleration_y = (float)accel.y * kFilteringFactor + acceleration_y * (1.0f - kFilteringFactor);
    acceleration_z = (float)accel.z * kFilteringFactor + acceleration_z * (1.0f - kFilteringFactor);

    accelerometerCounter++;
    if (accelerometerCounter == kUpdateCount)
    {
        [self initOrientation];
        [UIAccelerometer sharedAccelerometer].delegate = nil;
    }
}

- (void)initOrientation
{
    // Figure out orientation from acceleration_[xyz] and set up your UI...
}

Оригинальный ответ:

Возвращает ли [UIDevice currentDevice].orientation правильную ориентацию во время applicationDidFinishLaunching:? Если это так, вы можете настроить свой первоначальный интерфейс в соответствии с этой ориентацией.

Если это свойство не будет установлено до более позднего времени, вы можете попробовать поэкспериментировать с performSelector:afterDelay:, чтобы инициализировать интерфейс после небольшой задержки.

Этот пример кода взят из ответа Кендалла, приведенного ниже, для полноты добавлен здесь:

[self performSelector:@selector(getOriented) withObject:nil afterDelay:0.0f];

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

1 голос
/ 18 января 2013

Вот один из способов получить ориентацию при первой загрузке приложения и установке UIDeviceOrientation на UIDeviceOrientationUnknown. Вы можете посмотреть на свойство transform повернутого вида.

if(toInterface == UIDeviceOrientationUnknown) {
    CGAffineTransform trans = navigationController.view.transform;
    if(trans.b == 1 && trans.c == -1)
        toInterface = UIDeviceOrientationLandscapeLeft;
    else if(trans.b == -1 && trans.c == 1)
        toInterface = UIDeviceOrientationLandscapeRight;
    else if(trans.a == -1 && trans.d == -1)
        toInterface = UIDeviceOrientationPortraitUpsideDown;
    else
        toInterface = UIDeviceOrientationPortrait;
}
1 голос
/ 11 апреля 2012

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

Не на 100% уверен, что это правильно, но мне не нравиться:

[[[UIApplication sharedApplication] statusBar] orientation]
1 голос
/ 24 июля 2009

Морт, эти ответы кажутся чем-то вроде красной сельди; Я не понимаю, почему вы не можете использовать следующий встроенный метод для класса UIViewController:

-(void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {}

Этот метод вызывается автоматически после того, как произошло вращение (а не с shouldAutorotateToInterfaceOrientation, который только сообщает, что это произойдет) Удобно, переменная fromInterfaceOrientation содержит предыдущую ориентацию. Как сказано в документации, вы можете предположить, что свойство interfaceOrientation представления уже было установлено в новую ориентацию, поэтому у вас есть один метод с доступом к старой и новой ориентации!

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

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

0 голосов
/ 02 сентября 2009

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

0 голосов
/ 21 июля 2009

В ответ на ваш комментарий я подумал, что мог бы лучше написать код здесь, чем в комментарии (хотя на самом деле Даниил заслуживает похвалы здесь):

в приложении DidFinishLaunching:

[self performSelector:@selector(getOriented) withObject:nil afterDelay:0.0f];

Тогда вам просто нужен метод для вызова:

- (void) getOriented 
{ 
   UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
   // save orientation somewhere
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...