¿Cómo mantener un UIView apuntando en cierta dirección independientemente de la orientación del dispositivo?

StackOverflow https://stackoverflow.com/questions/4870738

Pregunta

Tengo una vista de UIVIEW que quiero estar siempre enfrentando. Entonces, digamos que tiene un UIIMageView que tiene una flecha, y no importa de qué manera se retiene el dispositivo, está apuntando. Obviamente, necesito el acelerómetro, pero decirle que rota la imagen en función de las coordenadas solo funcionará la primera vez que creo, ya que las rotaciones son relativas. ¿Hay una forma más fácil de hacer esto? Siento que habría una aplicación de ejemplo simple en algún lugar que haría algo como esto.

¿Fue útil?

Solución

Apple tiene un código de muestra que hace exactamente lo que desea; Echa un vistazo a esto: http://developer.apple.com/library/ios/#samplecode/whichwayisup/introduction/intro.html

Para recibir datos de movimiento específicos, use la instancia compartida de UIAccelerometer Y es delegado. http://developer.apple.com/library/ios/documentation/uikit/reference/uiaccelerometerdelegate_protocol/uiaccelerometerdelegate/uiaccelerometerdelegate.html#//apple_ref/occ/intf/uiaccelerometerdelegate

En cuanto a las rotaciones, no estoy seguro. Eche un vistazo al código de muestra "Bubblelevel" aquí: http://developer.apple.com/library/ios/samplecode/bubblelevel/introduction/intro.html#//apple_ref/doc/uid/dts40007331

El acelerómetro delega documentación hace referencia a que y otro código de muestra relevante.

Otros consejos

Whywayisup es la aplicación de muestra que está buscando: en la biblioteca de referencia de iOS (¡excelentes documentos!)

Las transformaciones aplicadas a una vista no son acumulativas. Más bien, la vista comienza a estar alineada con el sistema de coordenadas de su padre, y la transformación se aplica en relación con eso.

Como otras respuestas han aludido, hay suficientes piezas en Apple's Código de muestra de BubBlelevel Para lograr lo que estás buscando. -[LevelViewController accelerometer:didAccelerate:] ya contiene un ejemplo de cómo extraer el componente de rotación relativo a la pantalla suavizado del vector de gravedad:

// Use a basic low-pass filter to only keep the gravity in the accelerometer values for the X and Y axes
accelerationX = acceleration.x * kFilteringFactor + accelerationX * (1.0 - kFilteringFactor);
accelerationY = acceleration.y * kFilteringFactor + accelerationY * (1.0 - kFilteringFactor);

// keep the raw reading, to use during calibrations
currentRawReading = atan2(accelerationY, accelerationX);

Dado los sistemas de coordenadas de UIACCeleración y atan2, hay algunos factores que necesitará tener en cuenta para calcular la rotación deseada de su punto de vista:

  1. Cuando el dispositivo está en posición vertical en el retrato, atan2 devolverá -π/2 (-90 °), ya que el vector de gravedad de entrada es {0.0, -1.0, 0.0}.
  2. CGAffineTransformMakeRotation crea una transformación que girará en sentido horario (en iOS) por el número especificado de radianes, pero el ángulo en bruto desde atan2 Especifica una rotación en sentido antihorario.

En consecuencia, querrá rotar su vista por -(CurrentRawreading + π/2), suponiendo que su vista principal esté orientada con la pantalla en retrato:

view.transform = CGAffineTransformMakeRotation(-(currentRawReading + M_PI/2));
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top