Есть ли способ определить ориентацию устройства, если представление загружается до вызова [window makeKeyAndVisible]? - PullRequest
1 голос
/ 30 июня 2011

Просмотр моего UIViewController загружается из NIB до вызова [window makeKeyAndVisible] в application:didFinishLaunchingWithOptions:, поэтому я не могу получить правильную ориентацию устройства - т.е. self.interfaceOrientation, [[UIApplication sharedApplication] statusBarOrientation] и [[UIDevice currentDevice] orientation] все дают мне неверную ориентациюинформация о том, что я нахожусь в портретном режиме (я думаю, это режим iPad по умолчанию).

Есть ли способ обойти эту проблему?Пожалуйста, не говорите, что мне нужно использовать акселерометр;)

РЕДАКТИРОВАТЬ: для тех, кто заинтересован в получении информации об ориентации на основе чтения акселерометра: http://web.archive.org/web/20091111033649/http://blog.sallarp.com/iphone-accelerometer-device-orientation

Ответы [ 2 ]

1 голос
/ 30 июня 2011

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

Как только вы в этой точкеUIViewController.interfaceOrientation представляется надежным.

1 голос
/ 30 июня 2011

кажется, что вы не можете положиться на [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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...