ios - tutorial - xcode create swift playground




comment verrouiller l'orientation portrait pour la vue principale uniquement avec swift (8)

Édité pour swift2.0:

override func shouldAutorotate() -> Bool {
        return false
}

override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
    return [.Portrait, .PortraitUpsideDown]
}

J'ai créé une application pour iPhone, à l'aide de swift , composée de nombreuses vues intégrées dans un contrôleur de navigation. Je souhaite verrouiller la vue principale en orientation Portrait et uniquement une sous-vue d'un contrôleur de navigation verrouillée en orientation Paysage. Voici un exemple de ce que je veux dire:

  • UINavigationController
    • UiViewController1 (verrouillé dans Portrait) Contrôleur de vue initial avec un bouton placé dans la barre de navigation qui donne à l'utilisateur la possibilité d'accéder à des listes où d'autres vues peuvent être sélectionnées
    • UIViewController2 (verrouillé en paysage)
    • UiViewController3 (Portrait et Paysage)
    • UiViewController4 (Portrait et Paysage)
    • ...
    • ...

Comment puis je faire ça?


Également répondu [here]

Lorsque vous avez une hiérarchie de vues complexe, les choses peuvent devenir compliquées, comme avoir plusieurs contrôleurs de navigation et / ou des contrôleurs de vue par onglet.

Cette implémentation impose aux contrôleurs de vue individuels de définir le moment où ils souhaitent verrouiller les orientations, au lieu de compter sur le délégué d'application pour les trouver en itérant des sous-vues ou en s'appuyant sur l'héritage.

Swift 3

Dans AppDelegate:

/// set orientations you want to be allowed in this property by default
var orientationLock = UIInterfaceOrientationMask.all

func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
        return self.orientationLock
}

Dans une autre classe globale de struct ou helper, j'ai créé ici AppUtility:

struct AppUtility {

    static func lockOrientation(_ orientation: UIInterfaceOrientationMask) {

        if let delegate = UIApplication.shared.delegate as? AppDelegate {
            delegate.orientationLock = orientation
        }
    }

    /// OPTIONAL Added method to adjust lock and rotate to the desired orientation
    static func lockOrientation(_ orientation: UIInterfaceOrientationMask, andRotateTo rotateOrientation:UIInterfaceOrientation) {

        self.lockOrientation(orientation)

        UIDevice.current.setValue(rotateOrientation.rawValue, forKey: "orientation")
    }

}

Ensuite, dans le ViewController souhaité, vous souhaitez verrouiller les orientations:

 override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    AppUtility.lockOrientation(.portrait)
    // Or to rotate and lock
    // AppUtility.lockOrientation(.portrait, andRotateTo: .portrait)

}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)

    // Don't forget to reset when view is being removed
    AppUtility.lockOrientation(.all)
}

Dans iOS8, si vous souhaitez verrouiller un ViewController spécifique, créez une extension de UINavigationController (si vous l'utilisez):

extension UINavigationController {
public override func shouldAutorotate() -> Bool {
if visibleViewController is YourViewController {
    return false
}
return true
}}

Dans le contrôleur principal où vous voulez portrait,

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

self.orientation = UIInterfaceOrientationMaskPortrait;
//Or self.orientation = UIInterfaceOrientationPortraitUpsideDown
}

et en subVC où vous voulez utiliser paysage

  self.orientation =  UIInterfaceOrientationLandscapeLeft:
   self.orientation =  UIInterfaceOrientationLandscapeRight:

ou vous pouvez remplacer cette méthode

- (NSUInteger)supportedInterfaceOrientations
{
  return UIInterfaceOrientationMaskPortrait;
} 

Voici comment je le ferais avec Obj-c dans iOS7. Je pense que ce code fonctionnerait aussi dans iOS8.


Même réponse de JasonJasonJason dans Swift 4 (cela fonctionnait correctement avec iOS 11 )

1- Remplacez DevraitAutorotate et SupportInterfaceOrientations pris en charge comme indiqué ci-dessous.

extension UINavigationController {

open override var shouldAutorotate: Bool {
    return true;
}

open override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    return (visibleViewController?.supportedInterfaceOrientations)!;
}}

2- Et votre contrôleur de vue principal (portrait en tout temps) devrait avoir:

 public override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    return UIInterfaceOrientationMask.portrait;
}

3- Ensuite, dans vos contrôleurs de sous-vues que vous souhaitez prendre en charge portrait ou paysage:

 public override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    return UIInterfaceOrientationMask.all;
}

Mise à jour: si vous rencontrez des difficultés pour définir l'orientation juste après le lancement de l'application dans iOS 10 , essayez de le faire dans ObjC au lieu de Swift et avec la class MyNavigationController: MyNavigationControllerBase :

@implementation ABNavigationControllerBase
- (NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskPortrait;
}
@end

Swift 3:

class MyNavigationController: UINavigationController {
    override func viewDidLoad() {
        super.viewDidLoad()
        UIDevice.current.setValue(UIInterfaceOrientation.portrait.rawValue, forKey: "orientation")
    }
    override var shouldAutorotate: Bool {
        return false
    }
    override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        return .portrait
    }
    override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
        return .portrait
    }
}

Voici la mise à jour rapide: -

override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
    return UIInterfaceOrientationMask.Portrait
}

Vous devez appliquer cela à votre contrôleur de vue supérieure. Cependant, vous pouvez le faire de manière propre / facile en sous-classant votre contrôleur de vue de dessus et en y définissant une variable qui fasse référence à des références chaque fois que vous appelez:

shouldAutoRotate()

appelé lorsque l’appareil détecte un changement d’orientation et précède l’appel de:

supportedInterfaceOrientations()//this is only called if shouldAutoRotate() returns true

Par exemple, disons que mon contrôleur de vue de dessus est un TabBarController:

class SomeSubclassTabBarViewController: UITabBarController { //This subclass allows us to pass along data to each of the tabBars

var dataArray = StoredValues()//also useful for passing info between tabs
var shouldRotate: Bool = false


override func shouldAutorotate() -> Bool { //allow the subviews accessing the tabBarController to set whether they should rotate or not
    return self.shouldRotate
}

}

Ensuite, dans la vue qui devrait pouvoir faire pivoter l'écran, définissez les propriétés viewWillAppear () et viewWillDisappear () comme suit:

override func viewWillAppear(animated: Bool) { //set the rotate capability to true
    let sharedTabBarController = self.tabBarController as SomeSubclassTabBarViewController
    sharedTabBarController.shouldRotate = true
}

override func viewWillDisappear(animated: Bool) {
    let sharedTabBarController = self.tabBarController as SomeSubclassTabBarViewController
    sharedTabBarController.shouldRotate = false
}

et juste au cas où votre application se bloquerait sur cet écran, c'est probablement une bonne idée de définir explicitement la valeur shouldRotate: Bool sur chacune de vos vues dans la méthode viewWillLoad ().







swift