Jak zablokować orientację jednego kontrolera widoku tylko w trybie portretowym w Swift

Ponieważ moja aplikacja ma wsparcie dla wszystkich orientacji. Chciałbym zablokować tylko tryb portretowy do określonego UIViewController.

Np. Załóżmy, że była to aplikacja z zakładkami i gdy Widok SignIn pojawia się modalnie, chcę tylko, aby ten widok SignIn był tylko w trybie portretowym, bez względu na to, jak użytkownik obraca urządzenie lub jak bieżąca orientacja urządzenia będzie

Author: Ronan Boiteau, 2015-03-09

16 answers

Rzeczy mogą być dość niechlujne, gdy masz skomplikowaną hierarchię widoków, jak posiadanie wielu kontrolerów nawigacji i / lub kontrolerów widoku kart.

Ta implementacja ustawia poszczególne Kontrolery widoku, kiedy chcą zablokować orientacje, zamiast polegać na delegacie aplikacji, aby je znaleźć poprzez iterację w podwidywaniach.

Swift 3, 4, 5

W 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
}

W jakiejś innej globalnej klasie STRUCT lub helper, tutaj stworzyłem "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")
        UINavigationController.attemptRotationToDeviceOrientation()
    }

}

Następnie w żądanym Viewcontrolle chcesz zablokować orientacje:

 override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(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)
}

Jeśli iPad lub Uniwersalna aplikacja

Upewnij się, że opcja "wymaga pełnego ekranu" jest zaznaczona w Ustawieniach celu -> ogólne -> informacje o wdrożeniu. supportedInterfaceOrientationsFor delegat nie zostanie wywołany, jeśli nie jest zaznaczony. Tutaj wpisz opis obrazka

 278
Author: bmjohns,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-08-24 14:35:43

Swift 4

Tutaj wpisz opis obrazka AppDelegate

var orientationLock = UIInterfaceOrientationMask.all

func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
    return self.orientationLock
}
struct AppUtility {
    static func lockOrientation(_ orientation: UIInterfaceOrientationMask) {
        if let delegate = UIApplication.shared.delegate as? AppDelegate {
            delegate.orientationLock = orientation
        }
    }

    static func lockOrientation(_ orientation: UIInterfaceOrientationMask, andRotateTo rotateOrientation:UIInterfaceOrientation) {
        self.lockOrientation(orientation)
        UIDevice.current.setValue(rotateOrientation.rawValue, forKey: "orientation")
    }
}

Twój ViewController Dodaj następującą linię, jeśli potrzebujesz tylko orientacji pionowej. musisz zastosować to do wszystkich kontrolerów ViewController trzeba wyświetlić tryb portretowy.

override func viewWillAppear(_ animated: Bool) {
AppDelegate.AppUtility.lockOrientation(UIInterfaceOrientationMask.portrait, andRotateTo: UIInterfaceOrientation.portrait)
    }

Oraz spowoduje to orientację ekranu dla innych kontrolerów Viewcontroller zgodnie z fizyczną orientacją urządzenia.

override func viewWillDisappear(_ animated: Bool) {
        AppDelegate.AppUtility.lockOrientation(UIInterfaceOrientationMask.all)

    }
 30
Author: Nahid Raihan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-09 09:25:46

Swift 3 & 4

Ustaw właściwość supportedInterfaceOrientations dla określonych kontrolerów UIViewControllers w następujący sposób:

class MyViewController: UIViewController {

    var orientations = UIInterfaceOrientationMask.portrait //or what orientation you want
    override var supportedInterfaceOrientations : UIInterfaceOrientationMask {
    get { return self.orientations }
    set { self.orientations = newValue }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    //...
}

UPDATE

To rozwiązanie działa tylko wtedy, gdy viewControllerjest a nie osadzone w UINavigationController, ponieważ orientacja dziedziczy z nadrzędnego kontrolera viewController.
W tym przypadku możesz utworzyć podklasę UINavigationViewController i ustawić na niej te właściwości.

 14
Author: Arash Etemad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-06-19 12:58:13

Dodaj ten kod, aby wymusić portret i zablokować go:

override func viewDidLoad() {
    super.viewDidLoad()

    // Force the device in portrait mode when the view controller gets loaded
    UIDevice.currentDevice().setValue(UIInterfaceOrientation.Portrait.rawValue, forKey: "orientation") 
}

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

override func supportedInterfaceOrientations() -> Int {

    // Only allow Portrait
    return Int(UIInterfaceOrientationMask.Portrait.rawValue)
}

override func preferredInterfaceOrientationForPresentation() -> UIInterfaceOrientation {

    // Only allow Portrait
    return UIInterfaceOrientation.Portrait
}

W Twoim AppDelegate-set supportedInterfaceOrientationsForwindow to whatever orientations you want the whole application to support:

func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> UIInterfaceOrientationMask {
    return UIInterfaceOrientationMask.All
} 
 10
Author: Valentin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-11 11:51:37

Dla nowej wersji Swift spróbuj tego

override var shouldAutorotate: Bool {
    return false
}

override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    return UIInterfaceOrientationMask.portrait
}

override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
    return UIInterfaceOrientation.portrait
}
 10
Author: Khemmachart Chutapetch,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-03-01 10:37:28

Jest to ogólne rozwiązanie twojego problemu i innych powiązanych.

1. Utwórz klasę pomocniczą UIHelper i zastosuj następujące metody:

    /**This method returns top view controller in application  */
    class func topViewController() -> UIViewController?
    {
        let helper = UIHelper()
        return helper.topViewControllerWithRootViewController(rootViewController: UIApplication.shared.keyWindow?.rootViewController)
    }

    /**This is a recursive method to select the top View Controller in a app, either with TabBarController or not */
    private func topViewControllerWithRootViewController(rootViewController:UIViewController?) -> UIViewController?
    {
        if(rootViewController != nil)
        {
            // UITabBarController
            if let tabBarController = rootViewController as? UITabBarController,
                let selectedViewController = tabBarController.selectedViewController {
                return self.topViewControllerWithRootViewController(rootViewController: selectedViewController)
            }

            // UINavigationController
            if let navigationController = rootViewController as? UINavigationController ,let visibleViewController = navigationController.visibleViewController {
                return self.topViewControllerWithRootViewController(rootViewController: visibleViewController)
            }

            if ((rootViewController!.presentedViewController) != nil) {
                let presentedViewController = rootViewController!.presentedViewController;
                return self.topViewControllerWithRootViewController(rootViewController: presentedViewController!);
            }else
            {
                return rootViewController
            }
        }

        return nil
    }

2. Utwórz protokół z zachowaniem pożądania, dla Twojego konkretnego przypadku będzie portret.

Protokół orientacjisonlyportrait {}

Nota: jeśli chcesz, dodaj go na górze klasy UIHelper.

3. Extend your View Controller

W Twoim przypadku:

class Any_ViewController: UIViewController,orientationIsOnlyPortrait {

   ....

}

4. W app delegate class dodaj tę metodę:

 func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
        let presentedViewController = UIHelper.topViewController()
        if presentedViewController is orientationIsOnlyPortrait {
            return .portrait
        }
        return .all
    }

Uwagi Końcowe:

  • jeśli więcej klas jest w trybie portretowym, po prostu rozszerz to protokół.
  • jeśli chcesz mieć inne zachowania z kontrolerów widoku, Utwórz inne protokoły i postępuj zgodnie z tą samą strukturą.
  • ten przykład rozwiązuje problem ze zmianami orientacji po push Kontrolery widoku
 8
Author: Ariel Antonio Fundora,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-27 19:55:08

Kilka świetnych odpowiedzi w tym wątku, ale żadna nie pasowała do moich potrzeb. Mam aplikację z kartami z kontrolerami nawigacyjnymi w każdej karcie, a jeden widok musiał się obrócić, podczas gdy inne musiały być zablokowane w pionie. Kontroler nawigacyjny z jakiegoś powodu nie zmieniał poprawnie rozmiaru podwidów. Znalazłem rozwiązanie (w Swift 3) łącząc się z tą odpowiedzią, A problemy z układem zniknęły. Utwórz strukturę według sugestii @bmjohns:

import UIKit

struct OrientationLock {

    static func lock(to orientation: UIInterfaceOrientationMask) {
        if let delegate = UIApplication.shared.delegate as? AppDelegate {
            delegate.orientationLock = orientation
        }
    }

    static func lock(to orientation: UIInterfaceOrientationMask, andRotateTo rotateOrientation: UIInterfaceOrientation) {
        self.lock(to: orientation)
        UIDevice.current.setValue(rotateOrientation.rawValue, forKey: "orientation")
    }
} 

Następnie podklasa UITabBarController:

    import UIKit

class TabBarController: UITabBarController, UITabBarControllerDelegate {
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        self.delegate = self
    }

    func tabBarControllerSupportedInterfaceOrientations(_ tabBarController: UITabBarController) -> UIInterfaceOrientationMask {
        if tabBarController.selectedViewController is MyViewControllerNotInANavigationControllerThatShouldRotate {
            return .allButUpsideDown
        } else if let navController = tabBarController.selectedViewController as? UINavigationController, navController.topViewController is MyViewControllerInANavControllerThatShouldRotate {
            return .allButUpsideDown
        } else {
            //Lock view that should not be able to rotate
            return .portrait
        }
    }

    func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
        if viewController is MyViewControllerNotInANavigationControllerThatShouldRotate {
            OrientationLock.lock(to: .allButUpsideDown)
        } else if let navController = viewController as? UINavigationController, navController.topViewController is MyViewControllerInANavigationControllerThatShouldRotate {
            OrientationLock.lock(to: .allButUpsideDown)
        } else {
            //Lock orientation and rotate to desired orientation
            OrientationLock.lock(to: .portrait, andRotateTo: .portrait)
        }
        return true
    }
}

Nie zapomnij zmienić klasy TabBarController w storyboardzie na nowo utworzoną podklasę.

 5
Author: russdub,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:47:19

Oto prosty sposób, który działa dla mnie z Swift 4.2( iOS 12.2), umieść to w UIViewController, dla którego chcesz wyłączyć shouldAutorotate:

override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    return .portrait
}

Część .portrait mówi, w której orientacji (- ach) mają pozostać, możesz to zmienić, jak chcesz. Wybory są: .portrait, .all, .allButUpsideDown, .landscape, .landscapeLeft, .landscapeRight, .portraitUpsideDown.

 4
Author: GregT,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-04-17 04:43:47

Aby ustawić orientację poziomą dla wszystkich widoków aplikacji i zezwolić tylko na jeden widok dla wszystkich orientacji (na przykład, aby móc dodać rolkę z aparatu):

W AppDelegate.swift: {]}

var adaptOrientation = false

In: didFinishLaunchingWithOptions

NSNotificationCenter.defaultCenter().addObserver(self, selector: "adaptOrientationAction:", name:"adaptOrientationAction", object: nil)

Gdzie indziej w AppDelegate.swift: {]}

func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> Int {
    return checkOrientation(self.window?.rootViewController)
}

func checkOrientation(viewController:UIViewController?)-> Int{
    if (adaptOrientation == false){
        return Int(UIInterfaceOrientationMask.Landscape.rawValue)
    }else {
        return Int(UIInterfaceOrientationMask.All.rawValue)
    }
}

func adaptOrientationAction(notification: NSNotification){
    if adaptOrientation == false {
        adaptOrientation = true
    }else {
        adaptOrientation = false
    }
}

Wtedy w przekonaniu, że ten, który chce mieć wszystkie orientacje:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
    if (segue.identifier == "YOURSEGUE") {
        NSNotificationCenter.defaultCenter().postNotificationName("adaptOrientationAction", object: nil)
    }
}

override func viewWillAppear(animated: Bool) {
    if adaptOrientation == true {
        NSNotificationCenter.defaultCenter().postNotificationName("adaptOrientationAction", object: nil)
    }
}

Ostatnią rzeczą jest zaznaczenie orientacji urządzenia: - Portret / Align = "Left" / - Pejzaż Prawy

 2
Author: iOS Flow,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-18 03:22:05

Utwórz nowe rozszerzenie za pomocą

import UIKit

extension UINavigationController {
    override open var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        return .portrait
    }
}

extension UITabBarController {
    override open var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        return .portrait
    }
}
 2
Author: Felipe Kimio,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-29 21:20:37

Najlepsze rozwiązanie do blokowania i zmiany orientacji w pionie i poziomie:

Obejrzyj ten film na YouTube:

Https://m.youtube.com/watch?v=4vRrHdBowyo

Ten tutorial jest najlepszy i prosty.

Lub użyj poniższego kodu:

Zobacz to zdjęcie

/ / 1 - w drugim viewcontrolle ustawiamy landscapeleft, a w pierwszym ViewController ustawiamy portrat:

/ / 2-Jeśli używasz NavigationController, powinieneś dodać rozszerzenie

import UIKit

class SecondViewController: UIViewController {


    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        UIDevice.current.setValue(UIInterfaceOrientation.landscapeLeft.rawValue, forKey: "orientation")
    }

    override open var shouldAutorotate: Bool {
        return false
    }

    override open var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        return .landscapeLeft
    }

    override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
        return .landscapeLeft
    }
    
    

    override func viewDidLoad() {
        super.viewDidLoad()
    }

//write The rest of your code in here


}

//if you use NavigationController, you should add this extension

extension UINavigationController {
    override open var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        return topViewController?.supportedInterfaceOrientations ?? .allButUpsideDown
    
    }
}
 2
Author: OliaPh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-07-24 01:43:44

Bmjohns - > jesteś moim wybawcą życia. Jest to jedyne działające rozwiązanie (ze strukturą AppUtility)

I ' ve created this class:

class Helper{
    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")
        }

    }
}

I postępuj zgodnie z instrukcjami, a wszystko działa idealnie dla Swift 3 -> Xcode w wersji 8.2.1

 1
Author: Stjepan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-10 08:50:43

W systemie iOS 10 i 11 iPad obsługuje przesuwanie i dzielenie widoku. Aby włączyć aplikację w widoku Slide Over i Split View, Requires full screen musi być niezaznaczone. Oznacza to, że zaakceptowana odpowiedź nie może być użyta , jeśli aplikacja chce obsługiwać przesuwanie i dzielenie widoku. Zobacz Więcej z Apple adaptacja rozszerzeń wielozadaniowości na iPada tutaj .

Mam rozwiązanie, które umożliwia (1) unchecking Requires full screen, (2) tylko jedną funkcję do zaimplementowania w appDelegate (zwłaszcza jeśli nie nie można modyfikować kontrolerów widoku docelowego), oraz (3) unikać wywołań rekurencyjnych. Nie potrzeba klasy pomocniczej ani rozszerzeń.

AppDelegate.swift (Swift 4)

func application(_ application: UIApplication,
                 supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
    // Search for the visible view controller
    var vc = window?.rootViewController
    // Dig through tab bar and navigation, regardless their order 
    while (vc is UITabBarController) || (vc is UINavigationController) {
        if let c = vc as? UINavigationController {
            vc = c.topViewController
        } else if let c = vc as? UITabBarController {
            vc = c.selectedViewController
        }
    }
    // Look for model view controller
    while (vc?.presentedViewController) != nil {
        vc = vc!.presentedViewController
    }
    print("vc = " + (vc != nil ? String(describing: type(of: vc!)) : "nil"))
    // Final check if it's our target class.  Also make sure it isn't exiting.
    // Otherwise, system will mistakenly rotate the presentingViewController.
    if (vc is TargetViewController) && !(vc!.isBeingDismissed) {
        return [.portrait]
    }
    return [.all]
}

Edit

@ bmjohns zauważył, że ta funkcja nie jest wywoływana na iPadzie. Zweryfikowałem i tak nie został wezwany. Tak więc zrobiłem trochę więcej testów i dowiedziałem się kilku faktów:

  1. odznaczyłem Requires full screen ponieważ chcę włączyć Slide Over i Slide View na iPadzie. To wymaga aplikacja do obsługi wszystkich 4 orientacji dla iPada, w Info.plist: Supported interface orientations (iPad).

Moja aplikacja działa tak samo jak Facebook: na iPhonie większość czasu jest zablokowana do portretu. Podczas oglądania obrazu na pełnym ekranie, pozwala użytkownikom obracać krajobraz dla lepszego widoku. Na iPadzie użytkownicy mogą obracać się w dowolnej orientacji w dowolnych kontrolerach widoku. Tak więc aplikacja wygląda ładnie, gdy iPad stoi na Smart Cover(Krajobraz po lewej).

  1. Dla iPada do wywołania application(_:supportedInterfaceOrientationsFor), W Info.plist, Zachowaj tylko portret dla iPad. Aplikacja straci możliwość przesuwania + dzielenia widoku. Ale możesz zablokować lub odblokować orientację dowolnego kontrolera widoku, w jednym miejscu i bez potrzeby modyfikowania klasy ViewController.

  2. Na koniec funkcja ta jest wywoływana w cyklu życia kontrolera widoku, gdy widok jest wyświetlany / usuwany. Jeśli Twoja aplikacja musi zablokować/odblokować / zmienić orientację w innym czasie, może nie działać

 1
Author: John Pang,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-09 01:50:54

Faktycznie Przetestowane rozwiązanie dla tego. w moim przykładzie muszę cała moja aplikacja powinna być w trybie pionowym, ale tylko jeden ekran orientacji powinna być w trybie poziomym. Ustaw orientację pionową dla aplikacji, zaznaczając tylko tryb portretowy

Kod w AppDelegate jak wyżej opisane odpowiedzi.

var orientationLock = UIInterfaceOrientationMask.all

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

static func lockOrientation(_ orientation: UIInterfaceOrientationMask) {
    if let delegate = UIApplication.shared.delegate as? AppDelegate {
        delegate.orientationLock = orientation
    }
}
static func lockOrientation(_ orientation: UIInterfaceOrientationMask, andRotateTo rotateOrientation:UIInterfaceOrientation) {
self.lockOrientation(orientation)     
UIDevice.current.setValue(rotateOrientation.rawValue, forKey: "orientation")
}  
}

Następnie zapisz ten kod, zanim twój kontroler orientacji poziomej zostanie zaprezentowany / wypchnięty.

override func viewWillAppear(_ animated: Bool) {  
super.viewWillAppear(animated)
AppDelegate.AppUtility.lockOrientation(UIInterfaceOrientationMask.portrait, andRotateTo: UIInterfaceOrientation.portrait)
}  

Następnie zapisz ten kod w actual viewcontroller (dla widoku poziomego)

override func viewWillAppear(_ animated: Bool) {  
super.viewWillAppear(animated)
AppDelegate.AppUtility.lockOrientation(UIInterfaceOrientationMask.landscape, andRotateTo: UIInterfaceOrientation.landscape)
}  
 1
Author: Gurpreet Singh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-01-13 11:45:06

Trochę eksperymentowałem i udało mi się znaleźć czyste rozwiązanie tego problemu. Podejście opiera się na tagowaniu widoku za pomocą view - > tag

W docelowym kontrolerze ViewController po prostu Przypisz znacznik do widoku głównego, jak w poniższym przykładzie kodu:

class MyViewController: BaseViewController {

  // declare unique view tag identifier
  static let ViewTag = 2105981;

  override func viewDidLoad()
  {
    super.viewDidLoad();
    // assign the value to the current root view
    self.view.tag = MyViewController.ViewTag;
  }

I wreszcie w AppDelegate.szybkie sprawdzenie, czy aktualnie wyświetlany widok jest Tym, który otagowaliśmy:

func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask
{
    if (window?.viewWithTag(DesignerController.ViewTag)) != nil {
        return .portrait;
    }
    return .all;
}

To podejście zostało przetestowane na moim symulatorze i wygląda na to, że działa dobrze.

Uwaga: the zaznaczony Widok zostanie również znaleziony, Jeśli bieżący MVC jest nakładany na jakiś kontroler ViewController w stosie nawigacyjnym.

 1
Author: Vlada,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-11-01 20:38:58

Dzięki @ bmjohn odpowiedzi powyżej. Oto działająca Xamarin / C# wersja kodu odpowiedzi, aby zaoszczędzić innym czas transkrypcji:

AppDelegate.cs

 public UIInterfaceOrientationMask OrientationLock = UIInterfaceOrientationMask.All;
 public override UIInterfaceOrientationMask GetSupportedInterfaceOrientations(UIApplication application, UIWindow forWindow)
 {
     return this.OrientationLock;
 }

Orientacja Statyczna.Klasa cs:

public static class OrientationUtility
{
    public static void LockOrientation(UIInterfaceOrientationMask orientation)
    {
        var appdelegate = (AppDelegate) UIApplication.SharedApplication.Delegate;
        if(appdelegate != null)
        {
            appdelegate.OrientationLock = orientation;
        }
    }

    public static void LockOrientation(UIInterfaceOrientationMask orientation, UIInterfaceOrientation RotateToOrientation)
    {
        LockOrientation(orientation);

        UIDevice.CurrentDevice.SetValueForKey(new NSNumber((int)RotateToOrientation), new NSString("orientation"));
    }
}

Kontroler Widoku:

    public override void ViewDidAppear(bool animated)
    {
       base.ViewWillAppear(animated);
       OrientationUtility.LockOrientation(UIInterfaceOrientationMask.Portrait, UIInterfaceOrientation.Portrait);
    }

    public override void ViewWillDisappear(bool animated)
    {
        base.ViewWillDisappear(animated);
        OrientationUtility.LockOrientation(UIInterfaceOrientationMask.All);
    }
 -1
Author: ccs_dev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-12 18:44:09