web-dev-qa-db-fra.com

Détecter le changement d'orientation iOS instantanément

J'ai un jeu dans lequel l'orientation de l'appareil affecte l'état du jeu. L'utilisateur doit basculer rapidement entre les orientations Paysage, Portrait et Paysage inversé. Jusqu'à présent, j'ai enregistré le jeu pour recevoir des notifications d'orientation via:

[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];

Mais il est beaucoup trop lent - il semble y avoir un second délai entre la rotation du téléphone et le déclenchement de la notification. J'ai besoin d'un moyen de détecter instantanément les changements d'orientation de l'appareil. J'ai essayé d'expérimenter le gyroscope, mais je ne le connais pas encore suffisamment pour savoir s'il s'agit ou non de la solution que je recherche.

53
GoldenJoe

Ce delay dont vous parlez est en fait un filtre pour empêcher les fausses notifications (non désirées) de changement d'orientation.

Pour une reconnaissance instantanée du changement d'orientation de l'appareil, il vous suffira de surveiller vous-même l'accéléromètre.

L'accéléromètre mesure l'accélération (y compris la gravité) dans les 3 axes. Vous ne devriez donc pas avoir de problème pour déterminer l'orientation réelle.

Quelques codes pour commencer à travailler avec accéléromètre peuvent être trouvés ici:

Comment créer une application iPhone - Partie 5: L'accéléromètre

Et ce blog de Nice couvre la partie mathématique:

tilisation de l'accéléromètre

23
Rok Jarc

Ajouter un notifiant dans la fonction viewWillAppear

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

Le changement d'orientation notifie cette fonction

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

qui à son tour appelle cette fonction où la trame moviePlayerController est orientée est gérée

- (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;
    }
}

dans viewDidDisappear supprimer la notification

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

Je suppose que c’est le le plus rapide peut avoir changé la vue selon l’orientation

143
Vimal Venugopalan

Pourquoi vous n'avez pas utilisé

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation

?

Ou vous pouvez utiliser ceci

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

Ou ca

-(void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation

J'espère que ça va être utile hibou)

21
Arthur

Pour mon cas, le traitement de UIDeviceOrientationDidChangeNotification n’était pas une bonne solution car elle s’appelle plus fréquente et UIDeviceOrientation n’est pas toujours égal à UIInterfaceOrientation à cause de (FaceDown, FaceUp).

Je m'en sers avec 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");
    }
}
11
B.S.

Essayez d’apporter vos modifications dans:

- (void) viewWillLayoutSubviews {}

Le code s'exécutera à chaque changement d'orientation au fur et à mesure que les sous-vues seront redéfinies.

5
powerj1984

La réponse @vimal n'a pas fourni de solution pour moi. Il semble que l'orientation ne soit pas l'orientation actuelle, mais l'orientation précédente. Pour résoudre ce problème, j'utilise [[UIDevice currentDevice] orientation]

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

Ensuite

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

Avec ce code, j'obtiens la position d'orientation actuelle.

5