web-dev-qa-db-fra.com

rotations iOS 6: supportéInterfaceOrientations ne fonctionne pas?

Je rencontre ce problème avec iOS 6 SDK: certains affichages doivent être autorisés à pivoter (par exemple, une vidéo), et d’autres ne le font pas ..___. Maintenant, je comprends que je dois vérifier toutes les orientations de la app.s Info.plist, puis triez dans chaque ViewController ce qui devrait se passer. Mais ça ne marche pas! L'application pivote toujours selon les orientations indiquées dans Info.plist.

Info.plist:

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

tout ViewController qui ne devrait pas être autorisé à pivoter:

//deprecated
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

- (NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskPortrait;
}

Observation: l'application passe en orientation paysage et portrait. Des idées pourquoi ou ce que je fais mal?

A bientôt, Marc

Edit: Mes dernières découvertes indiquent également que si vous voulez avoir une rotation à un moment donné dans votre application, vous devez activer les quatre directions de rotation dans les paramètres de votre projet ou dans Info.plist. Une alternative à cela est de remplacer 

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window

dans votre AppDelegate, qui remplace le fichier Info.plist. Il n’est plus possible de définir uniquement Portrait dans votre Info.plist, puis d’avoir une rotation dans un ViewController en remplaçant d’autantAutorotateToInterfaceOrientation ou supportedInterfaceOrientations. 

36
stk

Si votre ViewController est un enfant d'un UINavigationController ou d'un UITabBarController, c'est le parent qui vous pose problème. Vous devrez peut-être sous-classer ce contrôleur de vue parent, en remplaçant simplement ces méthodes InterfaceOrientation comme vous l'avez montré dans votre question.

MODIFIER:

Exemple pour portrait uniquement TabBarController

           @interface MyTabBarController : UITabBarController
            {
            }
            @end

            @implementation MyTabBarController

            // put your shouldAutorotateToInterfaceOrientation and other overrides here        
            - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
                return (interfaceOrientation == UIInterfaceOrientationPortrait);
            }

            - (NSUInteger)supportedInterfaceOrientations{ 
                return UIInterfaceOrientationMaskPortrait; 
            } 

        @end
31
CSmith

En ajoutant à la réponse de CSmith ci-dessus, le code suivant dans une sous-classe UINavigationController permet la délégation au contrôleur de la vue de dessus de la manière que je pensais que cela fonctionnerait au départ:

- (BOOL)shouldAutorotate;
{
    return YES;
}

- (NSUInteger)supportedInterfaceOrientations
{
    if ([[self topViewController] respondsToSelector:@selector(supportedInterfaceOrientations)])
        return [[self topViewController] supportedInterfaceOrientations];
    else
        return [super supportedInterfaceOrientations];
}
27
Evan Schoenberg

Voici une autre alternative à l'approche de CSmith.

Si vous souhaitez reproduire le comportement antérieur à iOS 6 lorsque toutes les vues de la pile de navigation/la barre d'onglets doivent s'accorder sur un ensemble d'orientations autorisé, indiquez-le dans votre sous-classe de UITabBarController ou UINavigationController:

- (NSUInteger)supportedInterfaceOrientations
{
    NSUInteger orientations = [super supportedInterfaceOrientations];

    for (UIViewController *controller in self.viewControllers)
        orientations = orientations & [controller supportedInterfaceOrientations];

    return orientations;
}
8
Glenn Schmidt

Essayez d'ajouter cette catégorie:

@interface UINavigationController(InterfaceOrientation)

@end

@implementation UINavigationController(InterfaceOrientation)

- (NSUInteger) supportedInterfaceOrientations {
    if (self.viewControllers.count > 0)
        return [[self.viewControllers objectAtIndex:0] supportedInterfaceOrientations];
    else
        return UIInterfaceOrientationMaskAll;
}

@end
2
Shimanski Artem

Pour les personnes utilisant UINavigationController et Swift, vous pouvez ajouter cette extension à votre projet. Après cela, les contrôleurs de navigation délèguent le contrôle à leur contrôleur enfant.

extension UINavigationController {
    override public func supportedInterfaceOrientations()
    -> UIInterfaceOrientationMask {
        if let ctrl = topViewController {
            return ctrl.supportedInterfaceOrientations()
        }
        return super.supportedInterfaceOrientations()
    }

    override public func shouldAutorotate() -> Bool {
        if let ctrl = topViewController {
            return ctrl.shouldAutorotate()
        }
        return super.shouldAutorotate()
    }
}
1
Alvivi

@ Réponse d'Alvivi mise à jour pour Swift 4 .

extension UINavigationController {

    // Look for the supportedInterfaceOrientations of the topViewController
    // Otherwise, viewController will rotate irrespective of the value returned by the ViewController
    override open var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        if let ctrl = self.topViewController {
            return ctrl.supportedInterfaceOrientations
        }
        return super.supportedInterfaceOrientations
    }

    // Look for the shouldAutorotate of the topViewController
    // Otherwise, viewController will rotate irrespective of the value returned by the ViewController
    override open var shouldAutorotate: Bool {
        if let ctrl = self.topViewController {
            return ctrl.shouldAutorotate
        }
        return super.shouldAutorotate
    }
}
0
Harikrishna Pai

Ajout supplémentaire à @CSmith et @EvanSchoenberg.

Si vous avez des vues en rotation et d'autres non, vous devez créer une instance personnalisée de UITabBarController, tout en laissant chaque UIViewController décider.

- (BOOL)shouldAutorotate;
{
    return YES;
}

- (NSUInteger)supportedInterfaceOrientations
{
    UIViewController * top;
    UIViewController * tab = self.selectedViewController;
    if([tab isKindOfClass:
        ([UINavigationController class])]) {
        top = [((UINavigationController *)tab)
                 topViewController];
    }

    if ([top respondsToSelector:@selector(supportedInterfaceOrientations)])
        return [top supportedInterfaceOrientations];
    else
        return [super supportedInterfaceOrientations];
}
0
SwiftArchitect