2009-07-21 17 views
12

En mi programa, estoy moviendo cosas en función de la rotación, pero no estoy rotando toda la vista. Estoy usando:cómo detecto la orientación del iPhone antes de girar

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; 

} 

Esto funciona siempre que, cuando se puso en marcha el programa, la orientación del dispositivo es el retrato, pero no si la orientación inicial es horizontal o al revés, porque [auto doRotationStuff] hace cambios con respecto a la diferencia de la orientación anterior.

¿Hay alguna forma de detectar la orientación durante el lanzamiento o justo antes de rotar el dispositivo?

Respuesta

3

Actualizado:

Por lo tanto, desde el comentario de discusión, parece que no se puede confiar en [UIDevice currentDevice].orientation hasta la orientación cambia realmente por primera vez. Si es así, probablemente puedas hackearlo obteniendo lecturas de acelerómetro sin formato.

#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... 
} 

respuesta original:

Hace [UIDevice currentDevice].orientation devolver la orientación correcta durante la applicationDidFinishLaunching:? De ser así, puede configurar su UI inicial de acuerdo con esa orientación.

Si esa propiedad no quede ajustado hasta algún tiempo después, es posible experimentar con performSelector:afterDelay: para inicializar la interfaz de usuario después de un pequeño retraso.

Este ejemplo de código es de la respuesta de Kendall a continuación, añade aquí para completar:

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

No estoy seguro de si es un cero segundos de retraso es suficiente - esto significa que el código para getOriented se ejecutará durante el primer paso a través del bucle de ejecución de eventos. Es posible que deba esperar más tiempo para que las lecturas del acelerómetro se registren en .

+0

Durante applicationDidFinishLaunching, [UIDevice currentDevice] .orientation es UIDeviceOrientationUnknown –

+0

no tengo ni idea de cómo me gustaría utilizar performSelector: afterDelay. ¿Puedes dar un ejemplo de código? –

+0

Intenté lo que dijiste pero incluso [self performSelector: @selector (getOriented) withObject: nil afterDelay: 10.0f]; no tuvo ningún efecto –

-1

En respuesta a tu comentario, pensé que podría poner un código mejor aquí que en un comentario (aunque en realidad Daniel merece el crédito aquí):

en applicationDidFinishLaunching:

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

continuación, sólo tiene la método para llamar:

- (void) getOriented 
{ 
    UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation]; 
    // save orientation somewhere 
} 
+0

Intenté lo que dijiste pero incluso [self performSelector: @selector (getOriented) withObject: nil afterDelay: 10.0f]; No tuvo ningún efecto –

+0

¿Cuál fue la orientación cuando se llamó diez segundos después? Parece que después de diez segundos se debe establecer la orientación ... o en ese momento, simplemente pregúntele al controlador de vista principal cuál es su orientación. –

+0

fue UIDeviceOrientationUnknown –

1

Mort, estas respuestas parecen algo así como una pista falsa; No puedo ver por qué no se puede utilizar el siguiente método integrado para una clase UIViewController:

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

Este método es llamado automáticamente después de producirse una rotación (en lugar de con shouldAutorotateToInterfaceOrientation que sólo te dice que es acerca suceder). Fácilmente, la variable 'fromInterfaceOrientation' contiene la orientación anterior. Como también dice la documentación, puede suponer que la propiedad interfaceOrientation de la vista ya se ha establecido en la nueva orientación, por lo que tiene un método con acceso a la orientación anterior y al nuevo.

Si me he perdido algo y ya has descartado poder utilizar este método, ¡me disculpo! Parece extraño que estés creando y almacenando una variable para la "orientación anterior" cuando se proporciona de forma gratuita en el método anterior.

Espero que ayude!

+0

Eso funcionaría si tuviera planeado rotar la interfaz, lo que no quiero hacer. –

0

Un ejemplo más completo sobre cómo obtener la orientación del dispositivo de lecturas de aceleración se puede encontrar here A medida que la solución se basa en lecturas de aceleración, que no funcionaría en el simulador, por lo que tendrá que trabajar en el dispositivo. .. Todavía busco una solución que funcione en el simulador.

12

Dependiendo de sus circunstancias, una opción más simple puede ser la propiedad interfaceOrientation de la clase UIViewController. Esto es correcto antes de una rotación.

+2

Gracias! No sabía que existía este campo. Estaba usando la orientación de UIDevice, que no fue muy útil. – Chris

+0

¡Es por eso que *** S.O Rocks! *** ... iba a Nugging Futz tratando de resolver un * * tos * * problema de orientación simple ... no hay pista ... la búsqueda da vuelta a la respuesta de delany. –

1

Utilice esto para la orientación de la IU si necesita determinar de qué manera está apuntando.

No es 100% seguro de que esto es correcto, pero salirse de la parte superior de mi cabeza:

[[[UIApplication sharedApplication] statusBar] orientation] 
1

Aquí hay una manera de conseguir la orientación cuando la aplicación se carga por primera y la UIDeviceOrientation se establece en UIDeviceOrientationUnknown. Puede ver la propiedad de transformación de la vista girada.

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; 
} 
+0

¡Esto es oro! Le dará la orientación de una vista. Lo usé con 'UIDeviceOrientationDidChangeNotification' para detectar mi orientación anterior. – cnotethegr8

Cuestiones relacionadas