Come mantenere un UIView che punta in una certa direzione indipendentemente dall'orientamento del dispositivo?

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

Domanda

Ho una Uiview che voglio essere sempre affrontato. Quindi dì che hai un uiimageview che ha una freccia, e non importa quale sia il dispositivo che si sta trattenendo, è rivolto verso l'alto. Ovviamente ho bisogno dell'accelerometro, ma dicendolo per ruotare l'immagine in base alle coordinate funzionerà solo la prima volta che penso, poiché le rotazioni sono relative. C'è un modo più semplice per farlo? Sento che ci sarebbe una semplice app di esempio da qualche parte che farebbe qualcosa del genere.

È stato utile?

Soluzione

Apple ha un codice di esempio che fa esattamente quello che vuoi; dai un'occhiata a questo: http://developer.apple.com/library/ios/#samplecode/whichwayisup/introduction/intro.html

Per ricevere dati di movimento specifici, utilizzare l'istanza condivisa di UIAccelerometer Ed è delegato. http://developer.apple.com/library/ios/documentation/uikit/reference/uiaccicerometerdelegate_protocol/uiaccicerometerdelegate/uiaccicerometerdelegate.html#//apple_ref/occ/intf/uiaccicerometerdelegate

Per quanto riguarda le rotazioni, non ne sono sicuro. Dai un'occhiata al codice di esempio "Bubblelevel" qui: http://developer.apple.com/library/ios/samplecode/bubblelevel/introduction/intro.html#//apple_ref/doc/uid/dts40007331

L'accelerometro delega la documentazione fa riferimento a quello e altro codice di esempio pertinente.

Altri suggerimenti

Whawayisup è l'applicazione di esempio che stai cercando - nella libreria di riferimento iOS (grandi documenti!)

Le trasformazioni applicate in una vista non sono cumulative. Piuttosto, la vista inizia a essere allineata al sistema di coordinate del suo genitore e la trasformazione viene applicata rispetto a quella.

Come hanno accennato altre risposte, ci sono abbastanza pezzi in Apple Codice campione di Bubblelevel Per realizzare quello che stai cercando. -[LevelViewController accelerometer:didAccelerate:] Contiene già un esempio di come estrarre la componente di rotazione correlata allo schermo levigato del vettore di gravità:

// 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);

Dati i sistemi di coordinate di Uiaccelerazione e Atan2, ci sono alcuni fattori che dovrai tenere a mente per calcolare la rotazione desiderata della tua vista:

  1. Quando il dispositivo è in posizione verticale nel ritratto, atan2 restituirà -π/2 (-90 °), poiché il vettore di gravità di ingresso è {0,0, -1,0, 0,0}.
  2. CGAffineTransformMakeRotation crea una trasformazione che ruoterà in senso orario (su iOS) dal numero specificato di radianti, ma l'angolo grezzo da atan2 Specifica una rotazione in senso antiorario.

Di conseguenza, ti consigliamo di ruotare la tua vista tramite -(currentRawReading + π/2), supponendo che la sua vista genitore sia orientata con lo schermo nel ritratto:

view.transform = CGAffineTransformMakeRotation(-(currentRawReading + M_PI/2));
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top