So sperren Sie die Ausrichtung eines Ansichts-Controllers nur in Swift im Hochformat

95

Da hat meine App Unterstützung für alle Orientierung bekommen. Ich möchte nur den Hochformatmodus für einen bestimmten UIViewController sperren.

Angenommen, es handelt sich um eine Anwendung mit Registerkarten. Wenn die Anmeldeansicht modal angezeigt wird, möchte ich nur, dass die Anmeldeansicht nur im Hochformat angezeigt wird, unabhängig davon, wie der Benutzer das Gerät dreht oder wie die aktuelle Geräteausrichtung sein wird

Thiha Aung
quelle

Antworten:

257

Wenn Sie eine komplizierte Ansichtshierarchie haben, wie z. B. mehrere Navigationscontroller und / oder Registerkartenansicht-Controller, kann es ziemlich chaotisch werden.

Bei dieser Implementierung müssen die einzelnen Ansichtscontroller festlegen, wann sie Ausrichtungen sperren möchten, anstatt sich darauf zu verlassen, dass der App-Delegierte sie durch Durchlaufen von Unteransichten findet.

Schnelle 3 & 4

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

In einer anderen globalen Struktur- oder Hilfsklasse habe ich hier AppUtility erstellt:

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()
    }

}

Dann möchten Sie im gewünschten ViewController die Ausrichtung sperren:

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

Wenn iPad oder Universal App

Stellen Sie sicher, dass unter Zieleinstellungen -> Allgemein -> Bereitstellungsinformationen die Option "Vollbild erforderlich" aktiviert ist. supportedInterfaceOrientationsForDer Delegat wird nicht angerufen, wenn dies nicht aktiviert ist. Geben Sie hier die Bildbeschreibung ein

bmjohns
quelle
Sieht aus wie es Code-Kontrolle ist ... lassen Sie mich es überprüfen, scheint eine gute Antwort.
Thiha Aung
17
Nach vielen wahnsinnigen Nachforschungen ist dies die einzige Antwort, die ich gefunden habe und die für mich funktioniert. Swift 3 - Xcode 8.2.1
Xavier Garcia Rubio
1
@pbm Einige der Anwendungen in der Firma, an denen ich arbeite, arbeiten an bestimmten Stellen in der App an Sperrorientierungen und wurden über viele Jahre hinweg mehrmals für den App Store genehmigt. Trotzdem kann ich nicht garantieren, dass Apple in Zukunft kein Problem damit haben wird. Aber bisher keine Probleme, und ich bin ziemlich sicher, dass viele Apps dies in irgendeiner Form tun.
Bmjohns
2
Wenn diese Option aktiviert Requires full screenist, wird verhindert, dass die App für Slide Over und Split View verfügbar ist. Siehe Übernahme von Multitasking-Verbesserungen auf dem iPad durch Apple. Ich habe eine Antwort, für die keine Aktivierung erforderlich istRequires full screen
John Pang
2
Es funktioniert nicht, das zweite viewController-Layout hat die Anzeige nur im Hochformat nicht aktualisiert.
Der iCoder
27

Swift 4

Geben Sie hier die Bildbeschreibung ein 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")
    }
}

Ihr ViewController Folgende Zeile hinzufügen , wenn Sie nur Hochformat benötigen. Sie müssen dies auf alle ViewController anwenden, die den Porträtmodus anzeigen müssen.

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

Dadurch wird die Bildschirmausrichtung für andere Viewcontroller entsprechend der physischen Ausrichtung des Geräts vorgenommen.

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

    }
Nahid Raihan
quelle
Für Swift 4 ist dies definitiv die beste Antwort. Es ist genau das, was ich brauchte, da es das Verhalten der iOS-Kamera-App nachahmt.
Nocdib
@Nahid Ersetzen wir das Original func application innerhalb des App-Delegaten durch diese Funktionfunc application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask { return self.orientationLock ?
Moondra
Nach ein oder zwei Stunden Suche nach einer Lösung und einigen Versuchen ist dies die perfekt funktionierende Lösung. Es legt die Ausrichtung der Ansicht fest, erzwingt sie beim Laden der Ansicht, entsperrt beim Wechseln zu einer anderen Ansicht, funktioniert in der Tab-Navigation und der Code ist einfach und sauber. Vielen Dank an @Nahid
Radek Sip
11

Schnelle 3 & 4

supportedInterfaceOrientationsLegen Sie die Eigenschaft bestimmter UIViewController wie folgt fest:

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()
    }

    //...
}

AKTUALISIEREN

Diese Lösung funktioniert nur , wenn Ihr viewControllerist nicht eingebettet in UINavigationController, weil die Orientierung erbt von Eltern Viewcontroller.
In diesem Fall können Sie eine Unterklasse von erstellen UINavigationViewControllerund diese Eigenschaften festlegen.

Arash Etemad
quelle
Vielen Dank. Dies funktioniert gut für mich, da ich nur eine bestimmte Ansicht auf das Porträt beschränken möchte. Nicht die gesamte App.
user3204765
Alles, was ich brauche, ist die Steuerung bestimmter Ansichts-Controller, um die Ausrichtung unabhängig von der Ausrichtung des Geräts zu sperren. Das hat großartig funktioniert!
Ryan B.
9

Fügen Sie diesen Code hinzu, um das Porträt zu erzwingen und zu sperren:

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
}

Stellen Sie in Ihrem AppDelegate supportInterfaceOrientationsForWindow auf die Ausrichtungen ein, die die gesamte Anwendung unterstützen soll:

func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> UIInterfaceOrientationMask {
    return UIInterfaceOrientationMask.All
} 
Valentin
quelle
Danke Valentin, ich habe Ihre Hilfe sehr geschätzt. Aber Ihr Code hat nicht funktioniert. Und ich habe ihn jetzt gelöst. Ich habe auch meine Frage beantwortet.
Thiha Aung
7

Dies ist eine generische Lösung für Ihr Problem und andere verwandte Probleme.

1. Erstellen Sie die Hilfsklasse UIHelper und wenden Sie die folgenden Methoden an:

    /**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. Erstellen Sie ein Protokoll mit Ihrem Wunschverhalten, denn Ihr spezieller Fall ist Porträt.

ProtokollorientierungIsOnlyPortrait {}

Hinweis: Wenn Sie möchten, fügen Sie es oben in der UIHelper-Klasse hinzu.

3. Erweitern Sie Ihren View Controller

In deinem Fall:

class Any_ViewController: UIViewController,orientationIsOnlyPortrait {

   ....

}

4. Fügen Sie in der App-Delegatenklasse die folgende Methode hinzu:

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

Schlussbemerkungen:

  • Wenn sich mehr Klassen im Hochformat befinden, erweitern Sie einfach dieses Protokoll.
  • Wenn Sie andere Verhaltensweisen von View Controllern möchten, erstellen Sie andere Protokolle und folgen Sie derselben Struktur.
  • Dieses Beispiel löst das Problem mit Orientierungsänderungen nach Push-View-Controllern
Ariel Antonio Fundora
quelle
Wie diese Lösung, aber ich fand die UIHelper-Funktionen nützlicher als Erweiterungen von UINavigationController.
Michael Long
5

Eine Reihe großartiger Antworten in diesem Thread, aber keine entsprach ganz meinen Bedürfnissen. Ich habe eine App mit Registerkarten mit Navigationssteuerungen in jeder Registerkarte, und eine Ansicht musste gedreht werden, während die anderen im Hochformat gesperrt werden mussten. Der Navigationscontroller hat aus irgendeinem Grund die Größe seiner Unteransichten nicht richtig geändert. Durch Kombinieren mit dieser Antwort wurde eine Lösung (in Swift 3) gefunden , und die Layoutprobleme verschwanden. Erstellen Sie die Struktur wie von @bmjohns vorgeschlagen:

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")
    }
} 

Dann Unterklasse 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
    }
}

Vergessen Sie nicht, die Klasse des TabBarControllers im Storyboard in die neu erstellte Unterklasse zu ändern.

russdub
quelle
5

Versuchen Sie dies für eine neue Version von Swift

override var shouldAutorotate: Bool {
    return false
}

override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    return UIInterfaceOrientationMask.portrait
}

override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
    return UIInterfaceOrientation.portrait
}
Khemmachart Chutapetch
quelle
Es ist genau das, was ich gebraucht wurde! Für den iPad-Controller sind alle Ausrichtungsoptionen gültig und für den iPhone-Controller nur der Porträtmodus, indem nur diese drei Überschreibungen eingegeben werden - Perfekt.
VYT
4

Hier ist eine einfache Methode, die für mich mit Swift 4.2 (iOS 12.2) UIViewControllerfunktioniert. Fügen Sie diese in eine Datei ein, für die Sie sollten deaktivieren sollten.

override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    return .portrait
}

Der .portraitTeil gibt an, in welcher Ausrichtung (en) Sie bleiben sollen. Sie können dies nach Belieben ändern. Zur Wahl stehen: .portrait, .all, .allButUpsideDown, .landscape, .landscapeLeft, .landscapeRight, .portraitUpsideDown.

GregT
quelle
2

So legen Sie die Querformatausrichtung auf alle Ansichten Ihrer App fest und lassen nur eine Ansicht auf Alle Ausrichtungen zu (um beispielsweise eine Kamerarolle hinzufügen zu können):

In AppDelegate.swift:

var adaptOrientation = false

In: didFinishLaunchingWithOptions

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

An anderer Stelle in 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
    }
}

Dann in der Ansicht, die zu der übergeht, möchten Sie in der Lage sein, alle Orientierungen zu haben:

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

Als letztes kreuzen Sie die Geräteorientierung an: - Hochformat - Querformat links - Querformat rechts

iOS Flow
quelle
2

Erstellen Sie eine neue Erweiterung mit

import UIKit

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

extension UITabBarController {
    override open var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        return .portrait
    }
}
Felipe Kimio
quelle
1

bmjohns -> Du bist mein Lebensretter. Dies ist die einzige funktionierende Lösung (mit der AppUtility-Struktur)

Ich habe diese Klasse erstellt:

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")
        }

    }
}

und befolgte Ihre Anweisungen, und alles funktioniert perfekt für Swift 3 -> xcode Version 8.2.1

Stjepan
quelle
1

Ab iOS 10 und 11 unterstützt das iPad Slide Over und Split View. Um eine App in Slide Over und Split View zu aktivieren, Requires full screen muss das Kontrollkästchen deaktiviert sein. Das bedeutet, dass die akzeptierte Antwort nicht verwendet werden kann, wenn die App Slide Over und Split View unterstützen möchte. Weitere Informationen zu Apples Einführung von Multitasking-Verbesserungen auf dem iPad finden Sie hier .

Ich habe eine Lösung, mit der (1) das Kontrollkästchen deaktiviert Requires full screen, (2) nur eine Funktion implementiert werden kann appDelegate(insbesondere, wenn Sie die Controller für die Zielansicht nicht ändern möchten / können) und (3) rekursive Aufrufe vermieden werden. Keine Notwendigkeit für Helferklasse oder Erweiterungen.

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

Bearbeiten

@bmjohns wies darauf hin, dass diese Funktion auf dem iPad nicht aufgerufen wird. Ich habe überprüft und ja, es wurde nicht aufgerufen. Also habe ich ein bisschen mehr getestet und einige Fakten herausgefunden:

  1. Ich habe das Kontrollkästchen deaktiviert, Requires full screenweil ich Slide Over und Slide View auf dem iPad aktivieren möchte. Dazu muss die App alle 4 Orientierungen für das iPad in Info.plist unterstützen : Supported interface orientations (iPad).

Meine App funktioniert genauso wie Facebook: Auf dem iPhone ist sie meistens an Hochformat gebunden. Wenn Sie das Bild im Vollbildmodus anzeigen, können Benutzer das Querformat drehen, um eine bessere Ansicht zu erhalten. Auf dem iPad können Benutzer in beliebigen Ansichts-Controllern in jede beliebige Ausrichtung drehen. Die App sieht also gut aus, wenn das iPad auf dem Smart Cover steht (Querformat links).

  1. Damit das iPad application(_:supportedInterfaceOrientationsFor)in Info.plist anruft, behalten Sie nur das Porträt für das iPad bei. Die App verliert die Fähigkeit Slide Over + Split View. Sie können die Ausrichtung für jeden View Controller jedoch an nur einer Stelle sperren oder entsperren, ohne die ViewController-Klasse ändern zu müssen.

  2. Schließlich wird diese Funktion im Lebenszyklus des View Controllers aufgerufen, wenn die Ansicht angezeigt / entfernt wird. Wenn Ihre App die Ausrichtung zu einem anderen Zeitpunkt sperren / entsperren / ändern muss, funktioniert sie möglicherweise nicht

John Pang
quelle
Funktioniert es für das iPhone? Ich möchte einen meiner viewController nur im Querformat anzeigen.
Der iCoder
Ja. Arbeit für das iPhone. Ich möchte einen meiner View-Controller sowohl im Hoch- als auch im Querformat und nach dem Löschen zum Hochformat zurückkehren.
John Pang
1

Tatsächlich getestete Lösung hierfür. In meinem Beispiel muss sich meine gesamte App im Hochformat befinden, aber nur die Ausrichtung eines Bildschirms sollte sich im Querformat befinden. Erstellen Sie eine Porträtausrichtung für die App, indem Sie nur den Porträtmodus aktivieren

Code in AppDelegate wie oben beschrieben.

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")
}  
}

Notieren Sie sich dann diesen Code, bevor Ihr Querformat-Ansichtscontroller angezeigt / gedrückt wird.

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

Notieren Sie sich dann diesen Code im aktuellen Viewcontroller (für Querformat)

override func viewWillAppear(_ animated: Bool) {  
super.viewWillAppear(animated)
AppDelegate.AppUtility.lockOrientation(UIInterfaceOrientationMask.landscape, andRotateTo: UIInterfaceOrientation.landscape)
}  
Gurpreet Singh
quelle
1

Ich habe ein wenig experimentiert und es geschafft, eine saubere Lösung für dieses Problem zu finden. Der Ansatz basiert auf dem View-Tagging über view-> tag

Weisen Sie im Ziel-ViewController das Tag wie im folgenden Codebeispiel der Stammansicht zu:

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

Und schließlich überprüfen Sie in AppDelegate.swift, ob die aktuell angezeigte Ansicht die ist, die wir markiert haben:

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

Dieser Ansatz wurde mit meinem Simulator getestet und scheint gut zu funktionieren.

Hinweis: Die markierte Ansicht wird auch gefunden, wenn sich die aktuelle MVC mit einem untergeordneten ViewController im Navigationsstapel überschneidet.

Vlada
quelle
0

Vielen Dank an die Antwort von @ bmjohn oben. Hier ist ein funktionierendes Xamarin / C # -Version des Codes dieser Antwort, um anderen die Zeit der Transkription zu ersparen:

AppDelegate.cs

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

Static OrientationUtility.cs Klasse:

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"));
    }
}

Controller anzeigen:

    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);
    }
ccs_dev
quelle
Ich verstehe nicht, wie relevant diese Antwort ist? Diese Person hat schnell gefragt und Sie haben in Xamarin gegeben.
Mihir Oza
0

Beste Lösung zum Sperren und Ändern der Ausrichtung im Hoch- und Querformat:

Sehen Sie sich dieses Video auf YouTube an:

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

Dieses Tutorial ist am besten und einfach.

oder verwenden Sie den folgenden Code:

Siehe dieses Bild

// 1- Im zweiten Viewcontroller setzen wir LandscapeLeft und im ersten Viewcontroller setzen wir Portrat:

// 2- Wenn Sie NavigationController verwenden, sollten Sie eine Erweiterung hinzufügen

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
    
    }
}
OliaPh
quelle