Ottenere l'orientamento del dispositivo prima di ruotarlo o forzarlo all'avvio. Qualche idea?

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

  •  08-07-2019
  •  | 
  •  

Domanda

Ho una scadenza presto e ho un bug molto fastidioso davanti a me e nessuna idea su come risolverlo. Il problema è che a volte il dispositivo non sa quale sia il suo orientamento prima che sia stato ruotato e quindi incasina i frame nelle istruzioni condizionali:

 if (orient == UIInterfaceOrientationPortrait || orient == 0){ 
  r = CGRectMake(0.0, 0.0, 320.0, 480.0);
        // draw stuff
    } else {
  r = CGRectMake(0.0, 0.0, 480.0, 320.0);
        // draw stuff
    }

Questo bug può essere facilmente riprodotto se tengo il dispositivo sul tavolo o nelle mani (posizione orizzontale) ed eseguo la mia applicazione, disegna rettangoli di tipo orizzontale nella schermata del tipo verticale.

Le mie domande sono: posso in qualche modo ottenere il giusto orientamento in questo tipo di situazione? Peccato che non possa essere riprodotto nel simulatore, quindi non sono sicuro che il codice che ho incollato sia responsabile di questo errore, ma quello è il posto in cui aggiusto i frame della vista in base all'orientamento. Forse c'è un altro (corretto) modo per farlo? E forse posso forzare l'applicazione in modalità verticale fino a quando non verrà attivato l'evento di rotazione?

È stato utile?

Soluzione

Non penso che sia un bug. Quando l'iPhone è seduto sul tavolo, tutta la gravità viene misurata lungo l'asse Z. Per determinare l'orientamento del dispositivo viene utilizzato l'asse x-y, ma nessuna accelerazione viene misurata accanto ad essi nel tuo scenario.

EDIT: ulteriori spiegazioni:

Questa immagine mostra come sono orientati gli assi su iPhone: alt text http://developer.apple. com / iphone / biblioteca / documentazione / UIKit / Reference / UIAcceleration_Class / Arte / device_axes.jpg

Quindi, quando hai l'iPhone sul retro, viene applicata un'accelerazione di -1g sull'asse z. Per ricevere le accelerazioni misurate è sufficiente registrare un delegato che implementa UIAccelerometerDelegate con l'istanza condivisa UIAccelerometer . Vedi AccelerometerGraph prova come è fatto.

Per determinare se l'iPhone si trova sul tavolo fai qualcosa del genere:

- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration
    {

    // lowPass filter first

    // now choose orientation
      if (fabs([acceleration z]) >= 0.9) // sitting on the table: choose new mode or lock current mode
      if (fabs([acceleration y]) >= 0.9) // probably portrait mode
      if (fabs([acceleration x]) >= 0.9) // probably landscape mode

    }

La precisione dell'accelerometro è 18mG = 0.018G quindi tienilo a mente. Inoltre, è necessario isolarsi dagli effetti dei cambi di movimento istantanei, un semplice filtro LowPass si adatta perfettamente a questa fattura. L'esempio AccelerometerGraph mostra come implementare tale filtro.

Scegli anche un intervallo di aggiornamento molto basso se non hai bisogno di molta precisione, 30Hz dovrebbe andare bene per i tuoi scopi.

Altri suggerimenti

Il sensore che determina l'orientamento del dispositivo non è né infallibile né intelligente. Se poni il telefono sul tavolo e poi lo cammini, come dovrebbe sapere che è sottosopra?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top