web-dev-qa-db-fra.com

iOS: orientation de l'appareil en charge

Il semble que lorsque mon application se charge, elle ne connaît pas son orientation actuelle:

UIInterfaceOrientation orientation = [[UIDevice currentDevice] orientation];
if (orientation == UIDeviceOrientationPortrait) {
    NSLog(@"portrait");// only works after a rotation, not on loading app
}

Une fois que je fais pivoter l'appareil, j'obtiens une orientation correcte, mais lorsque je charge l'application, sans changer d'orientation, il semble que l'utilisation de [[UIDevice currentDevice] orientation] ne connaisse pas l'orientation actuelle. 

Existe-t-il un autre moyen de vérifier cela lors du premier chargement de mon application?

51
Nic Hubbard

EDIT: J'ai mal lu votre question. Cela vous permettra de démarrer votre application dans certaines orientations. Je viens juste de réaliser que vous essayez de déterminer l'orientation du lancement.

Il existe une méthode pour vérifier l’orientation de la barre d’état sur UIApplication:

[[UIApplication sharedApplication] statusBarOrientation];

Réponse originale

Essayez de définir les orientations de périphérique acceptées par l'application dans le fichier Plist:

<key>UISupportedInterfaceOrientations</key>
<array>
    <string>UIInterfaceOrientationPortrait</string>
    <string>UIInterfaceOrientationLandscapeLeft</string>
    <string>UIInterfaceOrientationLandscapeRight</string>
</array>

Cela indiquera que votre application prend en charge Portrait (bouton d'accueil en bas), paysage de gauche et paysage de droite.

Ensuite, dans vos UIViewControllers, vous devrez redéfinir la méthode shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation) pour renvoyer YES lorsque l'application doit effectuer une rotation:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {

     return interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationLandscapeLeft || interfaceOrientation == UIInterfaceOrientationLandscapeRight;
}

Cela indiquera à UIViewController d'effectuer une rotation automatique si le périphérique est dans l'une de vos orientations prises en charge. Si vous souhaitez également prendre en charge l'orientation à l'envers (portrait avec le bouton d'accueil situé en haut), ajoutez-le à votre plist et renvoyez simplement YES en dehors de cette méthode.

Faites nous savoir comment cela marche.

65
groomsy

Je pense que ça va marcher:

 [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];UIInterfaceOrientation orientation = [UIDevice currentDevice].orientation;

Selon la référence UIDevice:
Citation:
"La valeur de cette propriété renvoie toujours 0 sauf si les notifications d'orientation ont été activées en appelant beginGeneratingDeviceOrientationNotifications"
J'avais initialement supposé que cette propriété contenait l'orientation actuelle à tout moment, mais apparemment pas. J'imagine que l'activation des notifications est gérée pour nous en coulisses dans d'autres situations où l'accès à la propriété d'orientation est généralement effectué. Il n'était donc pas évident que cela devait être fait manuellement dans le délégué de l'application.

11
Iducool

Une chose que personne n’a encore évoquée, c’est que vous stockez des types UIDeviceOrientation dans une variable UIInterfaceOrientation. Ils sont différents et ne doivent pas être traités comme des égaux. Notez que UIDeviceOrientationLeft est égal à UIInterfaceOrientationRight (étant donné que l’interface tourne dans le sens opposé à celui du périphérique).

2
Jeff Kelley

Lors du chargement, l'orientation du périphérique peut être .Unknown ou .FaceUp. Pour déterminer s'il s'agit d'un portrait ou d'un paysage, j'utilise la statusBarOrientation comme sauvegarde, comme ceci:

    var portraitOrientation = UIDevice.currentDevice().orientation == .Portrait

    if UIDevice.currentDevice().orientation == .Unknown || UIDevice.currentDevice().orientation == .FaceUp {
        portraitOrientation = UIApplication.sharedApplication().statusBarOrientation == .Portrait
    }

De cette façon, je peux assurer que portraitOrientation me dit toujours si le périphérique est en mode portrait, sinon, il le sera en mode paysage. Même en téléchargeant l'application pour la première fois.

2
Marijn

Vous pouvez le faire en insérant la notification suivante dans 

-(void)viewDidLoad

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(checkRotation:) name:UIApplicationDidChangeStatusBarOrientationNotification object:nil];

puis mettez la méthode suivante dans votre classe

-(void)checkRotation:(NSNotification*)notification
{
    UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
    if(orientation == UIInterfaceOrientationLandscapeLeft || orientation == UIInterfaceOrientationLandscapeRight)
    {
         //Do your textField animation here
    }
}

La méthode ci-dessus vérifie l’orientation de la barre d’état de l’ipad ou de l’iPhone et vous permet d’effectuer votre animation dans l’orientation requise.

2
Aragon

le problème est que [UIDevice currentDevice]orientation] indique parfois l'orientation incorrecte du périphérique.

utilisez plutôt [[UIApplication sharedApplication]statusBarOrientation] qui est une UIInterfaceOrientation donc pour le vérifier, vous devrez utiliser la fonction UIInterfaceOrientationIsLandscape(orientation)

j'espère que cela t'aides.

1
iksnae

Swift 3 basé sur le code de @Marjin.

var portraitOrientation = UIDevice.current.orientation == .portrait

if UIDevice.current.orientation == .unknown || UIDevice.current.orientation == .faceUp {
     portraitOrientation = UIApplication.shared.statusBarOrientation == .portrait
}

if(portraitOrientation)
{
     // Portrait
}
else
{

}
1
Nacho Badia

Pour obtenir l'orientation à partir de la barre d'état, il est également important d'activer toutes les orientations dans le fichier Plist.

1
NicoRaf

Essayez l'accéléromètre pour obtenir sa lecture, UIAccelerometer, obtenez un accélérateur partagé, configurez son délégué, obtenez les lectures, déterminez l'orientation à partir de là.

0
DavidN

J'ai tout essayé et pas de bons résultats. Donc, ce que j'ai fait, comme je suis sur un ipad, a été de laisser tout le travail aux méthodes splitViewController pour invalider le bouton bar 

Pour portrait:

- (void)splitViewController:(UISplitViewController *)svc willHideViewController:(UIViewController *)aViewController withBarButtonItem:(UIBarButtonItem *)barButtonItem forPopoverController: (UIPopoverController *)pc { NSlog(@"portrait");}

Pour le paysage:

- (void)splitViewController:(UISplitViewController *)svc willShowViewController:(UIViewController *)aViewController invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem{ NSlog(@"landscape");}

cela fonctionne toujours sur charge.

0
user1008139

Essayez celui-ci [[UIApplication sharedApplication] statusBarOrientation];

ou mettre en œuvre celui-ci dans le délégué de l'application

(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
    UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
}

Ça marche

0
Garry

J'utilise toujours cet extrait de code de travail pour l'iphone 4:

-(void)deviceOrientationDidChange:(NSNotification *)notification{

//Obtaining the current device orientation
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];    

int value = 0;

if(orientation == UIDeviceOrientationPortrait)
{
    value = 0;

}else if(orientation == UIDeviceOrientationLandscapeLeft)
{
    value = 90;

}else if(orientation == UIDeviceOrientationLandscapeRight)
{

    value = -90;

}

CGAffineTransform cgCTM = CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(value));
[photoImageView setTransform:cgCTM];

}

0
Rudolf Stepan

pour ceux qui cherchent une réponse pour Swift 3 ou 4. ajoutez simplement ce code dans le bloc viewDidLoad ().

`let orientation = UIApplication.shared.statusBarOrientation
 if orientation == .portrait {
        // portrait   
 } else if orientation == .landscapeRight || orientation == 
.landscapeLeft{
         // landscape     
 }`
0
Bilal Şimşek

Essaye celui-là. c'est un travail pour moi. mal à l’heure où la méthode didfinishedlaunch ne détecte pas l’orientation du périphérique. sa prise par défaut en tant que portrait. alors. J'utilise pour vérifier l'orientation de la barre de statistiques. Je teste ce code. mettez-le dans la méthode didfinishedlaunch dans appdeleget. 

UIInterfaceOrientation orientation = [UIApplication sharedApplication] .statusBarOrientation;

if(orientation == 0) {//Default orientation
    //UI is in Default (Portrait) -- this is really a just a failsafe.

    NSLog("for portrait");


}else if(orientation == UIInterfaceOrientationPortrait || orientation == UIInterfaceOrientationPortraitUpsideDown)
{

    NSLog("portrait");
}else if(orientation == UIInterfaceOrientationLandscapeLeft || orientation == UIInterfaceOrientationLandscapeRight)
{

    NSLog("Landscap");
}
0
jenish

C'est la vraie réponse. Quand une application démarre, son orientation est inconnue. Il utilise shouldAutorotateToInterfaceOrientation et supportedInterfaceOrientations pour décider de l'orientation à choisir.

Regardez comment je lance un exemple d'application dans le simulateur iPhone 5.0 et faites-le pivoter à l'aide du code ci-dessous et des "Orientations d'interface prises en charge" avec les 4 orientations possibles:

20:44:08.218 RotationTestApp Supported orientation: Portrait
20:44:08.222 RotationTestApp Supported orientation: Portrait (upside-down)
20:44:08.225 RotationTestApp Supported orientation: Landscape (home button on the right)
20:44:08.225 RotationTestApp Supported orientation: Landscape (home button on the left)
20:44:08.226 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (current device orientation: UIDeviceOrientationUnknown, interface orientation wants: UIInterfaceOrientationPortrait)
20:44:08.237 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (current device orientation: UIDeviceOrientationUnknown, interface orientation wants: UIInterfaceOrientationPortrait)
20:44:08.239 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (current device orientation: UIDeviceOrientationUnknown, interface orientation wants: UIInterfaceOrientationPortrait)
20:44:08.240 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (current device orientation: UIDeviceOrientationUnknown, interface orientation wants: UIInterfaceOrientationPortrait)
20:44:09.817 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (device orientation: UIDeviceOrientationLandscapeLeft)
20:44:09.833 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (device orientation: UIDeviceOrientationLandscapeLeft)
20:44:11.030 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (device orientation: UIDeviceOrientationPortraitUpsideDown)
20:44:11.040 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (device orientation: UIDeviceOrientationPortraitUpsideDown)
20:44:12.599 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (device orientation: UIDeviceOrientationLandscapeRight)
20:44:12.609 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (device orientation: UIDeviceOrientationLandscapeRight)
20:44:13.301 RotationTestApp shouldAutorotateToInterfaceOrientation: YES (device orientation: UIDeviceOrientationPortraitUpsideDown)

J'ai vu beaucoup d'extraits de code, mais aucun d'entre eux ne fonctionne de manière générique (iPad et iPhone, iOS 5.0+).

Au lieu d'essayer avec try-this-try-that, placez ce qui suit dans votre racine vc:

#define ToNSString_BEGIN(T) \
NSString* T##ToNSString(T valueParameter) { \
switch (valueParameter) {

#define ToNSString_VALUE(value) \
case value: return @#value

#define ToNSString_END(T) \
} \
return @"(unknown)"; \
}

// NSString* UIInterfaceOrientationToNSString(UIInterfaceOrientation);
ToNSString_BEGIN(UIInterfaceOrientation);
ToNSString_VALUE(UIInterfaceOrientationPortrait);           // 1
ToNSString_VALUE(UIInterfaceOrientationPortraitUpsideDown); // 2
ToNSString_VALUE(UIInterfaceOrientationLandscapeLeft);      // 3
ToNSString_VALUE(UIInterfaceOrientationLandscapeRight);     // 4
ToNSString_END  (UIInterfaceOrientation);

// NSString* UIDeviceOrientationToNSString(UIDeviceOrientation);
ToNSString_BEGIN(UIDeviceOrientation);
ToNSString_VALUE(UIDeviceOrientationUnknown);               // 0
ToNSString_VALUE(UIDeviceOrientationPortrait);              // 1
ToNSString_VALUE(UIDeviceOrientationPortraitUpsideDown);    // 2
ToNSString_VALUE(UIDeviceOrientationLandscapeLeft);         // 3
ToNSString_VALUE(UIDeviceOrientationLandscapeRight);        // 4
ToNSString_VALUE(UIDeviceOrientationFaceUp);                // 5
ToNSString_VALUE(UIDeviceOrientationFaceDown);              // 6
ToNSString_END  (UIDeviceOrientation);



// Change this custom method to alter auto-rotation behavior on all supported iOS versions and platforms.
- (BOOL)allowAutoRotate:(UIInterfaceOrientation)interfaceOrientation
{
    NSUInteger interfaceOrientationAsMask = (1<<interfaceOrientation);
    return interfaceOrientationAsMask & [self supportedInterfaceOrientations];
}

// Reads from the project's-Info.plist
- (NSUInteger)supportedInterfaceOrientations
{
    static NSUInteger orientationsResult;

    if (!orientationsResult) {
        NSArray *supportedOrientations = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"UISupportedInterfaceOrientations"];

        for (id orientationString in supportedOrientations) {
            if ([orientationString isEqualToString:@"UIInterfaceOrientationPortrait"]) {
                orientationsResult |= UIInterfaceOrientationMaskPortrait;
                NSLog(@"Supported orientation: Portrait");
            } else if ([orientationString isEqualToString:@"UIInterfaceOrientationPortraitUpsideDown"]) {
                orientationsResult |= UIInterfaceOrientationMaskPortraitUpsideDown;
                NSLog(@"Supported orientation: Portrait (upside-down)");
            } else if ([orientationString isEqualToString:@"UIInterfaceOrientationLandscapeRight"]) {
                orientationsResult |= UIInterfaceOrientationMaskLandscapeRight;
                NSLog(@"Supported orientation: Landscape (home button on the left)");
            } else if ([orientationString isEqualToString:@"UIInterfaceOrientationLandscapeLeft"]) {
                orientationsResult |= UIInterfaceOrientationMaskLandscapeLeft;
                NSLog(@"Supported orientation: Landscape (home button on the right)");
            } else {
                NSLog(@"Unrecognized orientation '%@' in mainBundle plist, key UISupportedInterfaceOrientations", orientationString);
            }
        }
    }
   return orientationsResult;
}

// iOS 6+ (not yet used in 6.0.1)
- (BOOL)shouldAutorotate
{
    UIDeviceOrientation interfaceOrientationFromDevice = [UIDevice currentDevice].orientation;
    BOOL result = [self allowAutoRotate:interfaceOrientationFromDevice];
    NSString *currentDeviceOrientation = UIDeviceOrientationToNSString(interfaceOrientationFromDevice);
    NSLog(@"shouldAutorotate: %s (current orientation %@)", result ? "YES" : "NO", currentDeviceOrientation);
    return result;
}

// iOS 2.0 - 5.1 (iOS 6+ deprecated, 6.0.1 still works)
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    NSString* orientationString;
    UIDeviceOrientation interfaceOrientationFromDevice = [UIDevice currentDevice].orientation;

    if ((int)interfaceOrientation != (int)interfaceOrientationFromDevice) {
        orientationString = [NSString stringWithFormat:@"current device orientation: %@, interface orientation wants: %@",
                             UIDeviceOrientationToNSString(interfaceOrientationFromDevice),
                             UIInterfaceOrientationToNSString(interfaceOrientation)
                             ];
    } else {
        orientationString = [NSString stringWithFormat:@"device orientation: %@", UIDeviceOrientationToNSString(interfaceOrientationFromDevice)
                             ];
    }

    BOOL result = [self allowAutoRotate:interfaceOrientation];
    NSLog(@"shouldAutorotateToInterfaceOrientation: %s (%@)",
          result ? "YES" : "NO",
          orientationString);
    return result;
}

Le problème persiste des animations de séquence qui n'utilisent pas l'orientation actuelle. Je suppose que la solution consiste à sous-classer chaque VC et à donner une orientation à un délégué Push/Notifier au pop.

Aussi important: 

shouldAutorotateToInterfaceOrientation ne fonctionne pas

TabBarController et navigationControllers en mode paysage, épisode II

0
Barry