2015-07-27 20 views
7

Ho la seguente configurazione:Determina l'orientamento del dispositivo e il suo angolo risultante su una dimensione?

enter image description here

Un iPhone si trova con il display al soffitto su un tavolo (alfa = 0 gradi). Quando l'iPhone viene spostato verso l'alto come mostrato nell'immagine, l'angolo alfa aumenta.

Come si calcola il valore dell'angolo alfa senza occuparsi di altri assi che potrebbero cambiare. Sono interessato solo a questo asse.

Come ottengo l'angolo alfa corretto che l'iPhone ha quando si solleva dal tavolo? Come faccio a ricevere una notifica quando cambia il valore di alpha?

risposta

10

È possibile utilizzare la classe CMMotionManager per monitorare le modifiche al movimento del dispositivo.

Objective C

// Ensure to keep a strong reference to the motion manager otherwise you won't get updates 
self.motionManager = [[CMMotionManager alloc] init]; 
if (self.motionManager.deviceMotionAvailable) { 

    self.motionManager.deviceMotionUpdateInterval = 0.1; 

    // For use in the montionManager's handler to prevent strong reference cycle 
    __weak typeof(self) weakSelf = self; 

    NSOperationQueue *queue = [[NSOperationQueue alloc] init]; 
    [self.motionManager startDeviceMotionUpdatesToQueue:queue 
              withHandler:^(CMDeviceMotion *motion, NSError *error) { 

               // Get the attitude of the device 
               CMAttitude *attitude = motion.attitude; 

               // Get the pitch (in radians) and convert to degrees.           
               NSLog(@"%f", attitude.pitch * 180.0/M_PI); 

               dispatch_async(dispatch_get_main_queue(), ^{ 
                // Update some UI 
               }); 

              }]; 

    NSLog(@"Device motion started"); 
} 
else { 
    NSLog(@"Device motion unavailable"); 
} 

Swift

// Ensure to keep a strong reference to the motion manager otherwise you won't get updates 
motionManager = CMMotionManager() 
if motionManager?.deviceMotionAvailable == true { 

    motionManager?.deviceMotionUpdateInterval = 0.1; 

    let queue = NSOperationQueue() 
    motionManager?.startDeviceMotionUpdatesToQueue(queue, withHandler: { [weak self] (motion, error) -> Void in 

     // Get the attitude of the device 
     if let attitude = motion?.attitude { 
      // Get the pitch (in radians) and convert to degrees. 
      // Import Darwin to get M_PI in Swift 
      print(attitude.pitch * 180.0/M_PI) 

      dispatch_async(dispatch_get_main_queue()) { 
       // Update some UI 
      } 
     } 

    }) 

    print("Device motion started") 
} 
else { 
    print("Device motion unavailable"); 
} 

NSHipster è (come sempre) una grande fonte di informazioni, e l'articolo su CMDeviceMotion non fa eccezione.

+0

Grazie potresti essere che hai un'idea anche su questa domanda correlata? http://stackoverflow.com/questions/31643371/how-can-i-draw-and-rotate-an-arrow-at-an-orientation-in-3d-space – confile

+0

Come si invia l'aggiornamento a una coda in background ? Potresti estendere il tuo esempio – confile

+0

@confile L'uso di una coda di sfondo è descritto nell'articolo [articolo NSHipster collegato] (http://nshipster.com/cmdevicemotion/#queueing-up). Ho anche aggiornato la risposta. –