web-dev-qa-db-fra.com

Détection de l'orientation iOS UIDevice

Je dois détecter lorsque l'appareil est en orientation portrait afin de pouvoir lancer une animation spéciale. Mais je ne veux pas que ma vue tourne automatiquement.

Comment remplacer une vue en rotation automatique lorsque l'appareil est tourné en mode portrait? Mon application n'a besoin que d'afficher sa vue en paysage, mais il semble que je doive également prendre en charge le portrait si je veux pouvoir détecter une rotation vers le portrait.

69
Jace999

Essayez de faire ce qui suit lorsque l'application se charge ou lorsque votre vue se charge:

[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter]
   addObserver:self selector:@selector(orientationChanged:)
   name:UIDeviceOrientationDidChangeNotification
   object:[UIDevice currentDevice]];

Ajoutez ensuite la méthode suivante:

- (void) orientationChanged:(NSNotification *)note
{
   UIDevice * device = note.object;
   switch(device.orientation)
   {
       case UIDeviceOrientationPortrait:
       /* start special animation */
       break;

       case UIDeviceOrientationPortraitUpsideDown:
       /* start special animation */
       break;

       default:
       break;
   };
}

Ce qui précède vous permettra de vous inscrire aux changements d'orientation de l'appareil sans activer la rotation automatique de votre vue.


Remarque

Dans tous les cas dans iOS, lorsque vous ajoutez un observateur, supprimez-le également aux moments appropriés (éventuellement, mais pas toujours, lorsque la vue apparaît/disparaît). Vous ne pouvez avoir que des "paires" de code d'observation/de désobservation. Si vous ne le faites pas, l'application se bloquera. Choisir où observer/désobserver dépasse le cadre de cet AQ. Cependant, vous devez avoir un "unobserve" pour correspondre au code "observe" ci-dessus.

170
David M. Syzdek

Si vous êtes venu à cette question en cherchant comment détecter un changement d'orientation (sans nécessairement vouloir désactiver la rotation), vous devez également être conscient de viewWillTransitionToSize , qui est disponible depuis iOS 8 .

Exemple rapide de ici

override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {

    coordinator.animateAlongsideTransition({ (UIViewControllerTransitionCoordinatorContext) -> Void in

        let orient = UIApplication.sharedApplication().statusBarOrientation

        switch orient {
        case .Portrait:
            println("Portrait")
            // Do something
        default:
            println("Anything But Portrait")
            // Do something else
        }

        }, completion: { (UIViewControllerTransitionCoordinatorContext) -> Void in
            println("rotation completed")
    })

    super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
}

Et si vous n'avez pas à vous soucier de l'orientation réelle:

override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {

    // do something

    super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
}

Exemple Objective-C de ici

- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{   
    [coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context)
    {
        UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
        // do whatever
    } completion:^(id<UIViewControllerTransitionCoordinatorContext> context)
    { 

    }];

    [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
}

Et si vous n'avez pas à vous soucier de l'orientation réelle (tirée de cette réponse ):

- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
    // Do view manipulation here.
    [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
}

Voir également

17
Suragch

1) Swift version de la réponse de David 2) Dans le cas où vous souhaitez toujours détecter l'orientation quand il n'y a pas de changement d'orientation (Swift vesion of Moe's answer to How I I detect the orientation of the appareil sur iOS? )

    // Initial device orientation
    let orientation: UIInterfaceOrientation = UIApplication.sharedApplication().statusBarOrientation
    if(orientation == UIInterfaceOrientation.Unknown){
        // code for Unknown
    }
    else if(orientation == UIInterfaceOrientation.Portrait){
        // code for Portrait
    }
    else if(orientation == UIInterfaceOrientation.PortraitUpsideDown){
        // code for Portrait
    }
    else if(orientation == UIInterfaceOrientation.LandscapeRight){
        // code for Landscape        
    }
    else if(orientation == UIInterfaceOrientation.LandscapeLeft){
        // ode for Landscape
    }

    // To detect device orientation change
    UIDevice.currentDevice().beginGeneratingDeviceOrientationNotifications()
    NSNotificationCenter.defaultCenter().addObserver(
        self,
        selector: "orientationChanged:",
        name: UIDeviceOrientationDidChangeNotification,
        object: UIDevice.currentDevice())

fonction orientationChanged

func orientationChanged(note: NSNotification)
{
    let device: UIDevice = note.object as! UIDevice
    switch(device.orientation)
    {
        case UIDeviceOrientation.Portrait:
        // code for Portrait
        break
        case UIDeviceOrientation.PortraitUpsideDown:
        // code for Portrait
        break
        case UIDeviceOrientation.LandscapeLeft:
        // code for Landscape
        break
        case UIDeviceOrientation.LandscapeRight:
        // code for Landscape
        break
        case UIDeviceOrientation.Unknown:
        // code for Unknown
        break
        default:
        break
    }
}
3
Tsuneyuki Ohsaki

Si je vous comprends bien, votre application est uniquement en mode paysage. Vous pouvez simplement spécifier dans la configuration des applications qu'il s'agit uniquement de paysage et n'avez donc pas à vous soucier de la rotation. L'application démarrera en mode paysage et y restera quelle que soit la façon dont l'iPad est orienté.

1
drekka

Si vous ne souhaitez pas créer d'objet périphérique, vous pouvez également utiliser

-(void) seObserverForOrientationChanging
{
    [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
    [[NSNotificationCenter defaultCenter]
     addObserver:self selector:@selector(orientationChanged:)
     name:UIDeviceOrientationDidChangeNotification
     object:[UIDevice currentDevice]];
}


- (void) orientationChanged:(NSNotification *)note
{
    if (UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation)){
        //Do something in landscape
    }
    else {
        //Do something in portrait
    }
}
0
B.Kosmowski

.UIDeviceOrientationDidChange la notification est appelée plusieurs fois sur l'iphone même lorsque l'appareil ne tourne pas. Je ne connais pas la raison, mais si vous en avez besoin uniquement lorsque l'appareil tourne vraiment, procédez comme suit.

NotificationCenter.default.addObserver(self, selector: #selector(orientationChanged), name: .UIDeviceOrientationDidChange, object: nil)

La méthode appelée depuis l'observateur devrait ressembler à ceci:

func orientationChanged() {

    if traitCollection.isIphone {

        defer {
            self.previousTraitCollectionForIphone = traitCollection
        }

        guard let previousTraitCollectionForIphone = previousTraitCollectionForIphone else {

            updateView()
            return
        }

        if previousTraitCollectionForIphone != traitCollection {
            updateView()
        }

    } else {
        updateView()
    }
}
0

Tout d'abord, désactivez tout sauf l'orientation souhaitée (pour qu'elle ne tourne pas)

Ensuite, comme David l'a dit, obtenez simplement l'orientation actuelle de l'appareil:

https://developer.Apple.com/library/ios/#documentation/EventHandling/Conceptual/EventHandlingiPhoneOS/MotionEvents/MotionEvents.html

Alternativement, vous pouvez simplement utiliser l'accéléromètre vous-même (car c'est de cette façon qu'il est fait de toute façon) et vérifier où se trouve la gravité pour voir son orientation. Si vous adoptez cette approche, vous pouvez jouer avec les valeurs vous-même pour obtenir des résultats différents.

0
Pochi