2012-08-23 8 views
51

Ho un gioco in cui l'orientamento del dispositivo influenza lo stato del gioco. L'utente deve passare rapidamente tra gli orientamenti Orizzontale, Verticale e Orizzontale inverso. Finora ho la registrazione del gioco per le notifiche di orientamento tramite:Rilevamento immediato dell'orientamento iOS

[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; 

Ma è troppo lento - ci sembra essere circa un secondo di ritardo tra ruotando il telefono e la notifica in realtà essere licenziato. Ho bisogno di un modo per rilevare IMMEDIATAMENTE le modifiche nell'orientamento del dispositivo. Ho provato a sperimentare con il giroscopio, ma non ne ho ancora abbastanza familiarità per sapere se è la soluzione che sto cercando.

+0

Qui si va, utilizzare questo [Link] (http://stackoverflow.com/questions/5559652/how-do-i-detect-the-orientation- of-the-device-on-ios). Per favore fatemi sapere se c'è qualche dubbio. – Sandy

+0

http://tech-blog.maddyzone.com/javascript/detect-orientation-event articolo molto bello –

risposta

22

Che ritardo si sta parlando è in realtà un filtro per impedire false (indesiderate) notifiche di modifica dell'orientamento.

Per instant riconoscimento del cambio di orientamento del dispositivo devi solo monitorare l'accelerometro da solo.

L'accelerometro misura l'accelerazione (gravità inclusa) su tutti e 3 gli assi, pertanto non si dovrebbe avere alcun problema nel determinare l'orientamento effettivo.

del codice per iniziare a lavorare con accelerometro può essere trovato qui:

How to make an iPhone App – Part 5: The Accelerometer

E questo bel blog copre la parte di matematica:

Using the Accelerometer

+0

UIAccelerometro obsoleto e sostituito da Core Motion –

+1

Il secondo collegamento è interrotto. –

21

Perché si `t utilizzare

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 

?

oppure è possibile utilizzare questo

-(void) willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration 

O questo

-(void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation 

speranza che civetta essere utile)

+8

Questi metodi NON verranno chiamati automaticamente sui controller di visualizzazione figlio. –

+1

Questi metodi sono ora deprecati. – Satyam

141

Aggiungi un notificante nella funzione viewWillAppear

-(void)viewWillAppear:(BOOL)animated{ 
    [super viewWillAppear:animated]; 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationChanged:) name:UIDeviceOrientationDidChangeNotification object:nil]; 
} 

La variazione dell'orientamento notifichi questa funzione

- (void)orientationChanged:(NSNotification *)notification{ 
    [self adjustViewsForOrientation:[[UIApplication sharedApplication] statusBarOrientation]]; 
} 

che a sua volta, chiama questa funzione in cui il telaio moviePlayerController è orientamento viene gestito

- (void) adjustViewsForOrientation:(UIInterfaceOrientation) orientation { 

    switch (orientation) 
    { 
     case UIInterfaceOrientationPortrait: 
     case UIInterfaceOrientationPortraitUpsideDown: 
     { 
     //load the portrait view  
     } 

      break; 
     case UIInterfaceOrientationLandscapeLeft: 
     case UIInterfaceOrientationLandscapeRight: 
     { 
     //load the landscape view 
     } 
      break; 
     case UIInterfaceOrientationUnknown:break; 
    } 
} 

in viewDidDisappear rimuovere la notifica

-(void)viewDidDisappear:(BOOL)animated{ 
    [super viewDidDisappear:animated]; 
    [[NSNotificationCenter defaultCenter]removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil]; 
} 

Credo che questo è il più veloce u può hanno cambiato il panorama come da orientamento

+4

Non dimenticare [super viewWillAppear: animato] e [super viewDidDisappear: animated] in caso di copia incolla come fanno i veri programmatori. –

+0

Nota: UIDeviceOrientation! = UIInterfaceOrientation. – nnrales

5

provare a fare le modifiche in:

- (void) viewWillLayoutSubviews {}

Il codice verrà eseguito ad ogni orientamento cambia quando le sottoview vengono di nuovo disposte.

5

La risposta @vimal non ha fornito soluzioni per me. Sembra che l'orientamento non sia l'orientamento corrente, ma dall'orientamento precedente. Per risolvere il problema, io uso [[UIDevice currentDevice] orientation]

- (void)orientationChanged:(NSNotification *)notification{ 
    [self adjustViewsForOrientation:[[UIDevice currentDevice] orientation]]; 
} 

Poi

- (void) adjustViewsForOrientation:(UIDeviceOrientation) orientation { ... } 

Con questo codice ottengo la posizione orientamento corrente.

10

Per il mio caso la gestione di UIDeviceOrientationDidChangeNotification non era una buona soluzione in quanto è denominata più frequente e UIDeviceOrientation non è sempre uguale a UIInterfaceOrientation a causa di (FaceDown, FaceUp).

mi occupo utilizzando UIApplicationDidChangeStatusBarOrientationNotification:

//To add the notification 
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didChangeOrientation:) 

//to remove the 
[[NSNotificationCenter defaultCenter]removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil]; 

... 

- (void)didChangeOrientation:(NSNotification *)notification 
{ 
    UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation; 

    if (UIInterfaceOrientationIsLandscape(orientation)) { 
     NSLog(@"Landscape"); 
    } 
    else { 
     NSLog(@"Portrait"); 
    } 
} 
Problemi correlati