it-swarm.com.de

Wie erzwinge ich die Ausrichtung des View Controllers in iOS 8?

Vor iOS 8 haben wir den folgenden Code in Verbindung mit den Delegierungsmethoden supportedInterfaceOrientations und shouldAutoRotate verwendet, um die Ausrichtung der App auf eine bestimmte Ausrichtung zu erzwingen. Ich habe das folgende Code-Snippet verwendet, um die App programmgesteuert in die gewünschte Ausrichtung zu drehen. Erstens ändere ich die Ausrichtung der Statusleiste. Wenn Sie dann nur eine modale Ansicht anzeigen und sofort schließen, wird die Ansicht in die gewünschte Ausrichtung gedreht.

[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:YES];
UIViewController *c = [[UIViewController alloc]init];
[self presentViewController:vc animated:NO completion:nil];
[self dismissViewControllerAnimated:NO completion:nil];

Aber dies schlägt in iOS 8 fehl. Außerdem habe ich einige Antworten im Stapelüberlauf gesehen, in denen Leute vorgeschlagen haben, dass wir diesen Ansatz ab iOS 8 immer vermeiden sollten.

Genauer gesagt handelt es sich bei meiner Bewerbung um eine universelle Bewerbungsform. Insgesamt gibt es drei Controller.

  1. First View-Controller - Es sollte alle Ausrichtungen auf dem iPad und nur Hochformat (Home-Taste gedrückt) auf dem iPhone unterstützen.

  2. Second View Controller - Es sollte nur Querformat unter allen Bedingungen unterstützen

  3. Third View Controller - Es sollte nur Querformat unter allen Bedingungen unterstützen

Wir verwenden den Navigationscontroller für die Seitennavigation. Vom ersten Ansichtscontroller aus drücken wir auf Knopfdruck die zweite auf den Stapel. Wenn der zweite View-Controller unabhängig von der Geräteorientierung eintrifft, sollte die App nur im Querformat aktiviert werden.

Unten sind meine Methoden shouldAutorotate und supportedInterfaceOrientations im zweiten und dritten Ansichtscontroller aufgeführt.

-(NSUInteger)supportedInterfaceOrientations{
    return UIInterfaceOrientationMaskLandscapeRight;
}

-(BOOL)shouldAutorotate {
    return NO;
}

Gibt es eine Lösung für diese oder eine bessere Möglichkeit zum Sperren eines View-Controllers in einer bestimmten Ausrichtung für iOS 8. Bitte helfen Sie!

142

Für iOS 7 - 10:

Ziel c:

[[UIDevice currentDevice] setValue:@(UIInterfaceOrientationLandscapeLeft) forKey:@"orientation"];
[UINavigationController attemptRotationToDeviceOrientation];

Swift 3:

let value = UIInterfaceOrientation.landscapeLeft.rawValue
UIDevice.current.setValue(value, forKey: "orientation")
UINavigationController.attemptRotationToDeviceOrientation()

Nennen Sie es einfach in - viewDidAppear: des vorgestellten View Controllers.

300
Sunny Shah

Das Drehen der Ausrichtung ist etwas komplizierter, wenn Sie sich in einem UINavigationController oder UITabBarController befinden. Das Problem besteht darin, dass, wenn ein Ansichts-Controller in einen dieser Controller eingebettet ist, der Navigations- oder Registerkarten-Controller Vorrang hat und Entscheidungen über die Autorotation und die unterstützten Ausrichtungen trifft.

Ich verwende die folgenden 2 Erweiterungen für UINavigationController und UITabBarController, damit Ansichtscontroller, die in einen dieser Controller eingebettet sind, die Entscheidungen treffen können.

Geben Sie den View Controllern die Kraft!

Swift 2.3

extension UINavigationController {
    public override func supportedInterfaceOrientations() -> Int {
        return visibleViewController.supportedInterfaceOrientations()
    }
    public override func shouldAutorotate() -> Bool {
        return visibleViewController.shouldAutorotate()
    }
}

extension UITabBarController {
    public override func supportedInterfaceOrientations() -> Int {
        if let selected = selectedViewController {
            return selected.supportedInterfaceOrientations()
        }
        return super.supportedInterfaceOrientations()
    }
    public override func shouldAutorotate() -> Bool {
        if let selected = selectedViewController {
            return selected.shouldAutorotate()
        }
        return super.shouldAutorotate()
    }
}

Swift 3

extension UINavigationController {
    open override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        return visibleViewController?.supportedInterfaceOrientations ?? super.supportedInterfaceOrientations
    }

    open override var shouldAutorotate: Bool {
        return visibleViewController?.shouldAutorotate ?? super.shouldAutorotate
    }
}

extension UITabBarController {
    open override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        if let selected = selectedViewController {
            return selected.supportedInterfaceOrientations
        }
        return super.supportedInterfaceOrientations
    }

    open override var shouldAutorotate: Bool {
        if let selected = selectedViewController {
            return selected.shouldAutorotate
        }
        return super.shouldAutorotate
    }
}

Jetzt können Sie die supportedInterfaceOrientations -Methode überschreiben, oder Sie können shouldAutoRotate im zu sperrenden Ansichts-Controller überschreiben. Andernfalls können Sie die Überschreibungen in anderen Ansichts-Controllern auslassen, die die Standardausrichtung übernehmen sollen Verhalten, das in der Liste Ihrer App angegeben ist

Drehung deaktivieren

class ViewController: UIViewController {
    override func shouldAutorotate() -> Bool {
        return false
    }
}

Auf bestimmte Ausrichtung fixieren

class ViewController: UIViewController {
    override func supportedInterfaceOrientations() -> Int {
        return Int(UIInterfaceOrientationMask.Landscape.rawValue)
    }
}

Theoretisch sollte dies für alle komplexen View-Controller-Hierarchien funktionieren, aber ich habe ein Problem mit UITabBarController festgestellt. Aus irgendeinem Grund möchte es einen Standardausrichtungswert verwenden. Lesen Sie den folgenden Blog-Beitrag, wenn Sie erfahren möchten, wie Sie einige der Probleme umgehen können:

Bildschirmdrehung sperren

91
Korey Hinton

Das hat bei mir funktioniert:

https://developer.Apple.com/library//ios/documentation/UIKit/Reference/UIViewController_Class/index.html#//Apple_ref/occ/clm/UIViewController/attemptRotationToDeviceOrientation

Nennen Sie es in Ihrer viewDidAppear: -Methode.

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

    [UIViewController attemptRotationToDeviceOrientation];
}
23
Vincil Bishop

Ich habe festgestellt, dass Sie preferredInterfaceOrientationForPresentation überschreiben können, wenn es sich um einen präsentierten Ansichtscontroller handelt.

Schnell:

override func supportedInterfaceOrientations() -> Int {
  return Int(UIInterfaceOrientationMask.Landscape.rawValue)
}

override func preferredInterfaceOrientationForPresentation() -> UIInterfaceOrientation {
  return UIInterfaceOrientation.LandscapeLeft
}

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

Dieser Weg funktioniert für mich in Swift 2 iOS 8.x:

PS (für diese Methode ist es nicht erforderlich, Orientierungsfunktionen wie "shouldautorotate" auf jedem viewController zu überschreiben, sondern nur eine Methode in AppDelegate)

Aktivieren Sie das Kontrollkästchen "Vollbild erforderlich" in den allgemeinen Informationen zu Ihrem Projekt. enter image description here

Machen Sie also auf AppDelegate.Swift eine Variable:

var enableAllOrientation = false

Setzen Sie also auch diese Funktion ein:

func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> UIInterfaceOrientationMask {
        if (enableAllOrientation == true){
            return UIInterfaceOrientationMask.All
        }
        return UIInterfaceOrientationMask.Portrait
}

Daher können Sie in jeder Klasse Ihres Projekts diese Variable in viewWillAppear festlegen:

override func viewWillAppear(animated: Bool)
{
        super.viewWillAppear(animated)
        let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
        appDelegate.enableAllOrientation = true
}

Wenn Sie eine Auswahl basierend auf dem Gerätetyp treffen müssen, können Sie dies tun:

override func viewWillAppear(animated: Bool)
    {
        super.viewWillAppear(animated)
        let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
        switch UIDevice.currentDevice().userInterfaceIdiom {
        case .Phone:
        // It's an iPhone
           print(" - Only portrait mode to iPhone")
           appDelegate.enableAllOrientation = false
        case .Pad:
        // It's an iPad
           print(" - All orientation mode enabled on iPad")
           appDelegate.enableAllOrientation = true
        case .Unspecified:
        // Uh, oh! What could it be?
           appDelegate.enableAllOrientation = false
        }
    }
15

Zuallererst - das ist eine schlechte Idee, im Allgemeinen stimmt etwas nicht mit Ihrer App-Architektur, aber, sh..t happens, wenn ja, können Sie versuchen, etwas wie das Folgende zu machen:

final class OrientationController {

    static private (set) var allowedOrientation:UIInterfaceOrientationMask = [.all]

    // MARK: - Public

    class func lockOrientation(_ orientationIdiom: UIInterfaceOrientationMask) {
        OrientationController.allowedOrientation = [orientationIdiom]
    }

    class func forceLockOrientation(_ orientation: UIInterfaceOrientation) {
        var mask:UIInterfaceOrientationMask = []
        switch orientation {
            case .unknown:
                mask = [.all]
            case .portrait:
                mask = [.portrait]
            case .portraitUpsideDown:
                mask = [.portraitUpsideDown]
            case .landscapeLeft:
                mask = [.landscapeLeft]
            case .landscapeRight:
                mask = [.landscapeRight]
        }

        OrientationController.lockOrientation(mask)

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

Dann in AppDelegate

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    // do stuff
    OrientationController.lockOrientation(.portrait)
    return true
}

// MARK: - Orientation

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

Und wann immer Sie die Ausrichtung ändern möchten, tun Sie Folgendes:

OrientationController.forceLockOrientation(.landscapeRight)

Hinweis: Manchmal kann es vorkommen, dass das Gerät bei einem solchen Anruf nicht aktualisiert wird. Daher müssen Sie möglicherweise die folgenden Schritte ausführen

OrientationController.forceLockOrientation(.portrait)
OrientationController.forceLockOrientation(.landscapeRight)

Das ist alles

10
gbk

Dies sollte ab iOS 6 funktionieren, ich habe es jedoch nur unter iOS 8 getestet. Unterklasse UINavigationController und überschreibe die folgenden Methoden:

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
    return UIInterfaceOrientationLandscapeRight;
}

- (BOOL)shouldAutorotate {
    return NO;
}

Oder fragen Sie den sichtbaren Ansichtscontroller

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
    return self.visibleViewController.preferredInterfaceOrientationForPresentation;
}

- (BOOL)shouldAutorotate {
    return self.visibleViewController.shouldAutorotate;
}

und implementieren Sie die Methoden dort.

9
Mojo66

Dies ist eine Rückmeldung zu Kommentaren in Sid Shahs Antwort , wie Animationen deaktiviert werden können mit:

[UIView setAnimationsEnabled:enabled];

Code:

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

    // Stackoverflow #26357162 to force orientation
    NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeRight];
    [[UIDevice currentDevice] setValue:value forKey:@"orientation"];
}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:NO];
    [UIView setAnimationsEnabled:YES];
}
9
ohho

Auf Xcode 8 Die Methoden werden in Eigenschaften konvertiert, daher funktioniert Folgendes mit Swift:

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

override public var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
    return UIInterfaceOrientation.portrait
}

override public var shouldAutorotate: Bool {
    return true
}
6
Ali Momen Sani

Wenn Sie den navigationViewController verwenden, sollten Sie hierfür eine eigene Superklasse erstellen und Folgendes überschreiben:

- (BOOL)shouldAutorotate {
  id currentViewController = self.topViewController;

  if ([currentViewController isKindOfClass:[SecondViewController class]])
    return NO;

  return YES;
}

dies deaktiviert die Rotation in SecondViewController , aber wenn Sie Ihren SecondViewController drücken, wenn Ihr Befindet sich das Gerät im Hochformat, wird Ihr SecondViewController im Hochformat angezeigt.

Angenommen, Sie verwenden ein Storyboard. Sie müssen manuell segue erstellen ( How to ) und in Ihrer "onClick" -Methode:

- (IBAction)onPlayButtonClicked:(UIBarButtonItem *)sender {
  NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeLeft];
  [[UIDevice currentDevice] setValue:value forKey:@"orientation"];
  [self performSegueWithIdentifier:@"PushPlayerViewController" sender:self];
}

Dadurch wird die Querformatausrichtung erzwungen, bevor die Autorotationsfunktion der Superklasse deaktiviert wird.

6
Lau

Ich habe viele Lösungen ausprobiert, aber die, für die gearbeitet hat, ist die folgende:

Es ist nicht notwendig, den info.plist In iOS 8 und 9 zu bearbeiten.

- (BOOL) shouldAutorotate {
    return NO;
}   

- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
    return (UIInterfaceOrientationPortrait | UIInterfaceOrientationPortraitUpsideDown);
}

Mögliche Ausrichtungen aus der Apple Documentation :

UIInterfaceOrientationUnknown

Die Ausrichtung des Geräts kann nicht bestimmt werden.

UIInterfaceOrientationPortrait

Das Gerät befindet sich im Hochformat, wobei das Gerät aufrecht gehalten wird und sich die Home-Taste unten befindet.

UIInterfaceOrientationPortraitUpsideDown

Das Gerät befindet sich im Hochformat, ist jedoch auf dem Kopf stehend, und die Home-Taste befindet sich oben.

UIInterfaceOrientationLandscapeLeft

Das Gerät befindet sich im Querformat, wobei das Gerät aufrecht gehalten wird und sich die Home-Taste auf der linken Seite befindet.

UIInterfaceOrientationLandscapeRight

Das Gerät befindet sich im Querformat, wobei das Gerät aufrecht gehalten wird und sich die Home-Taste auf der rechten Seite befindet.

4
hoogw

Die Kombination von Sids- und Koreys-Antworten hat bei mir funktioniert.

Erweiterung des Navigationscontrollers:

extension UINavigationController {
    public override func shouldAutorotate() -> Bool {
        return visibleViewController.shouldAutorotate()
    }
}

Deaktivieren Sie dann die Drehung in der Einzelansicht

class ViewController: UIViewController {
    override func shouldAutorotate() -> Bool {
        return false
    }
}

Und vor dem Übergang in die richtige Richtung drehen

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if (segue.identifier == "SomeSegue")
    {
        let value = UIInterfaceOrientation.Portrait.rawValue;
        UIDevice.currentDevice().setValue(value, forKey: "orientation")
    }
}
3
Misha

[iOS9 +] Wenn jemand den ganzen Weg nach unten gezogen hat, da keine der oben genannten Lösungen funktioniert hat, und wenn Sie die Ansicht anzeigen, deren Ausrichtung Sie nach Segue ändern möchten, möchten Sie dies möglicherweise überprüfen.

Überprüfen Sie den Präsentationstyp Ihres Segues. Meins war 'über dem aktuellen Kontext'. Als ich es auf Vollbild umgestellt habe, hat es funktioniert.

Dank @GabLeRoux habe ich diese Lösung gefunden.

  • Diese Änderung funktioniert nur in Kombination mit den oben genannten Lösungen.
2
Goh

Meine Anforderungen sind

  1. sperren Sie alle Ansichten im Hochformat
  2. benutze AVPlayerViewController um das Video abzuspielen

Wenn es sich bei dem wiedergegebenen Video um eine Landschaft handelt, können Sie den Bildschirm nach rechts und links drehen. Wenn es sich um ein Porträt handelt, sperren Sie die Ansicht nur im Porträtmodus.

Definieren Sie zuerst supportedInterfaceOrientationsForWindow in AppDelegate.Swift

var portrait = true
func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> UIInterfaceOrientationMask {
    if portrait {
        return .Portrait
    } else {
        return .Landscape
    }
}

Zweitens definieren Sie in Ihrem Hauptansichts-Controller die folgenden Funktionen

override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
    print("\(#function)")
    return .Portrait
}

override func preferredInterfaceOrientationForPresentation() -> UIInterfaceOrientation {
    return .Portrait
}

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

Dann müssen Sie AVPlayerViewController in Unterklassen unterteilen

class MyPlayerViewController: AVPlayerViewController {

    var size: CGSize?

    var supportedOrientationMask: UIInterfaceOrientationMask?
    var preferredOrientation: UIInterfaceOrientation?

    override func viewDidLoad() {
        super.viewDidLoad()

        if let size = size {
            if size.width > size.height {
                self.supportedOrientationMask =[.LandscapeLeft,.LandscapeRight]
                self.preferredOrientation =.LandscapeRight
            } else {
                self.supportedOrientationMask =.Portrait
                self.preferredOrientation =.Portrait
            }
        }
    }

Überschreiben Sie diese drei Funktionen in MyPlayerViewController.Swift

override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
    return self.supportedOrientationMask!
}

override func preferredInterfaceOrientationForPresentation() -> UIInterfaceOrientation {
    return self.preferredOrientation!
}

Da der Benutzer die Gerätelandschaft möglicherweise nach links oder rechts drehen kann, muss die automatische Drehung auf true gesetzt werden

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

Erstellen Sie schließlich die Instanz MyPlayerViewController in Ihrem View-Controller und legen Sie den Wert für die Eigenschaftsgröße fest.

let playerViewController = MyPlayerViewController()

// Get the thumbnail  
let thumbnail = MyAlbumFileManager.sharedManager().getThumbnailFromMyVideoMedia(......)

let size = thumbnail?.size
playerViewController.size = size

Initiiere deinen Spieler mit dem richtigen videoUrl und weise ihn dann playerViewController zu. Viel Spaß beim Codieren!

2
charles.cc.hsu

Die Top-Lösung oben:

let value = UIInterfaceOrientation.LandscapeLeft.rawValue
UIDevice.currentDevice().setValue(value, forKey: "orientation")

hat bei mir nicht funktioniert, als ich es in viewDidAppear des präsentierten View-Controllers aufgerufen habe. Es hat jedoch funktioniert, als ich es in prepareForSegue im Presenting View Controller aufgerufen habe.

(Leider gibt es nicht genügend Rufpunkte, um diese Lösung zu kommentieren. Daher musste ich sie so hinzufügen.)

2
guido
- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    [UIViewController attemptRotationToDeviceOrientation];
}
2

Nach Korey Hintons Antwort

Swift 2.2:

extension UINavigationController {
    public override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
        return visibleViewController!.supportedInterfaceOrientations()
    }
    public override func shouldAutorotate() -> Bool {
        return visibleViewController!.shouldAutorotate()
    }
}


extension UITabBarController {
    public override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
        if let selected = selectedViewController {
            return selected.supportedInterfaceOrientations()
        }
        return super.supportedInterfaceOrientations()
    }
    public override func shouldAutorotate() -> Bool {
        if let selected = selectedViewController {
            return selected.shouldAutorotate()
        }
        return super.shouldAutorotate()
    }
}

Drehung deaktivieren

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

Festlegen der spezifischen Ausrichtung

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

Ich habe hier ein paar Lösungen ausprobiert und das Wichtigste ist, dass es der Root-View-Controller ist, der bestimmt, ob er rotiert oder nicht.

Ich habe das folgende Objective-C Projekt github.com/GabLeRoux/RotationLockInTabbedViewChild mit einem Arbeitsbeispiel für TabbedViewController wobei eine untergeordnete Ansicht rotieren darf und die andere untergeordnete Ansicht im Hochformat gesperrt ist.

Es ist nicht perfekt, aber es funktioniert und die gleiche Idee sollte für andere Arten von Stammansichten wie NavigationViewController funktionieren. :)

Child view locks parent orientation

1
GabLeRoux

Es scheint immer noch eine Debatte darüber zu geben, wie diese Aufgabe am besten gelöst werden kann. Deshalb dachte ich, ich würde meinen (Arbeits-) Ansatz teilen. Fügen Sie den folgenden Code in Ihre UIViewController -Implementierung ein:

- (void) viewWillAppear:(BOOL)animated
{
    [UIViewController attemptRotationToDeviceOrientation];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
    return (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft);
}

-(BOOL)shouldAutorotate
{
    return NO;
}

- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskLandscapeLeft;
}

In diesem Beispiel müssen Sie außerdem die zulässigen Geräteorientierungen in Ihren Projekteinstellungen auf "Links im Querformat" setzen (oder direkt in info.plist). Ändern Sie einfach die spezifische Ausrichtung, die Sie erzwingen möchten, wenn Sie etwas anderes als LandscapeLeft.

Der Schlüssel für mich war der attemptRotationToDeviceOrientation -Aufruf in viewWillAppear - ohne dass sich die Ansicht nicht richtig drehen würde, ohne das Gerät physisch zu drehen.

0
ViperMav

Ich habe das gleiche Problem und verschwende so viel Zeit dafür. Jetzt habe ich meine Lösung. Meine App-Einstellung unterstützt nur das Hochformat. Einige Bildschirme in meiner App müssen jedoch nur das Querformat aufweisen. Ich behebe sie mit einer Variablen isShouldRotate at AppDelegate. Und die Funktion bei AppDelegate:

func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> Int {
    if isShouldRotate == true {
        return Int(UIInterfaceOrientationMask.Landscape.rawValue)
    }
    return Int(UIInterfaceOrientationMask.Portrait.rawValue)
}

Und zum Schluss, wenn ein ViewControllerA Querformat benötigt. Tun Sie das einfach: vor Push/Present zu ViewControllerA zuweisen isShouldRotate to true. Vergessen Sie nicht, wenn pop/dismiss diesen Controller isShouldRotate zu false at viewWillDisappear zuweist.

0
lee

Nach der von @ sid-sha gezeigten Lösung muss man alles in das viewDidAppear: Methode, sonst erhalten Sie nicht die didRotateFromInterfaceOrientation: gefeuert, also so etwas wie:

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    UIInterfaceOrientation interfaceOrientation = [[UIApplication sharedApplication] statusBarOrientation];
    if (interfaceOrientation == UIInterfaceOrientationLandscapeLeft ||
        interfaceOrientation == UIInterfaceOrientationLandscapeRight) {
        NSNumber *value = [NSNumber numberWithInt:interfaceOrientation];
        [[UIDevice currentDevice] setValue:value forKey:@"orientation"];
    }
}
0
loretoparisi

Es sieht so aus, als ob selbst du hier so viele Antworten hast, dass mir niemand genügt hat. Ich wollte die Ausrichtung erzwingen und dann wieder zur Geräteorientierung zurückkehren, aber [UIViewController attemptRotationToDeviceOrientation]; hat einfach nicht funktioniert. Was das Ganze auch kompliziert gemacht hat, ist, dass ich shouldAutorotate basierend auf einer Antwort zu false hinzugefügt habe und nicht in allen Szenarien die gewünschten Effekte zurückdrehen konnte.

Das habe ich also getan:

Bevor Sie den Aufruf des Controllers in seinem Init-Konstruktor starten, gehen Sie wie folgt vor:

_userOrientation = UIDevice.currentDevice.orientation;
[UIDevice.currentDevice setValue:@(UIInterfaceOrientationPortrait) forKey:@"orientation"];
[self addNotificationCenterObserver:@selector(rotated:)
                               name:UIDeviceOrientationDidChangeNotification];

So speichere ich die letzte Geräteorientierung und registriere mich für das Ereignis der Orientierungsänderung. Das Ereignis der Orientierungsänderung ist einfach:

- (void)rotated:(NSNotification*)notification {
    _userOrientation = UIDevice.currentDevice.orientation;
}

Und aus Gründen der Uneinigkeit zwinge ich mich einfach zurück zu jeder Orientierung, die ich als Benutzer-Erklärung habe:

- (void)onViewDismissing {
    super.onViewDismissing;
    [UIDevice.currentDevice setValue:@(_userOrientation) forKey:@"orientation"];
    [UIViewController attemptRotationToDeviceOrientation];
}

Und das muss auch da sein:

- (BOOL)shouldAutorotate {
    return true;
}

- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskPortrait;
}

Und auch der Navigationscontroller muss an shouldAutorotate und supportedInterfaceOrientations delegieren, aber das haben die meisten Leute meines Erachtens schon.

PS: Tut mir leid, ich verwende einige Erweiterungen und Basisklassen, aber Namen sind ziemlich aussagekräftig, so dass das Konzept verständlich ist und noch mehr Erweiterungen macht, da es jetzt nicht zu hübsch ist.

0
Renetik

Meine Lösung

In AppDelegate:

func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> UIInterfaceOrientationMask {
    if let topController = UIViewController.topMostViewController() {
        if topController is XXViewController {
            return [.Portrait, .LandscapeLeft]
        }
    }
    return [.Portrait]
}

XXViewController ist der ViewController, den Sie im Querformat unterstützen möchten.

Dann würde Sunny Shahs Lösung in Ihrem XXViewController auf jeder iOS-Version funktionieren:

let value = UIInterfaceOrientation.LandscapeLeft.rawValue
UIDevice.currentDevice().setValue(value, forKey: "orientation")

Dies ist die Hilfsprogrammfunktion zum Auffinden des ViewControllers mit der höchsten Priorität.

extension UIViewController {

    /// Returns the current application's top most view controller.
    public class func topMostViewController() -> UIViewController? {
        let rootViewController = UIApplication.sharedApplication().windows.first?.rootViewController
        return self.topMostViewControllerOfViewController(rootViewController)
    }



    /// Returns the top most view controller from given view controller's stack.
    class func topMostViewControllerOfViewController(viewController: UIViewController?) -> UIViewController? {
        // UITabBarController
        if let tabBarController = viewController as? UITabBarController,
           let selectedViewController = tabBarController.selectedViewController {
            return self.topMostViewControllerOfViewController(selectedViewController)
        }

        // UINavigationController
        if let navigationController = viewController as? UINavigationController,
           let visibleViewController = navigationController.visibleViewController {
            return self.topMostViewControllerOfViewController(visibleViewController)
        }

        // presented view controller
        if let presentedViewController = viewController?.presentedViewController {
            return self.topMostViewControllerOfViewController(presentedViewController)
        }

        // child view controller
        for subview in viewController?.view?.subviews ?? [] {
            if let childViewController = subview.nextResponder() as? UIViewController {
                return self.topMostViewControllerOfViewController(childViewController)
            }
        }

        return viewController
    }

}
0
duan

Für mich hat die oberste Ebene VC, die zum Implementieren der Ausrichtungsüberschreibungen benötigt wird, keine Auswirkung, wenn die oberste Ebene VC nicht implementiert wird.

VC-main
    |
    -> VC 2
        |
        -> VC 3

Nur VC-Main wird angehört, hauptsächlich in meinen Tests.

0
bduhbya

Verwenden Sie diese Option, um die Ausrichtung des View-Controllers zu sperren. Getestet mit IOS 9:

// Ausrichtung auf Querformat rechts fixieren

-(UIInterfaceOrientationMask)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskLandscapeRight;
}

-(NSUInteger)navigationControllerSupportedInterfaceOrientations:(UINavigationController *)navigationController {
    return UIInterfaceOrientationMaskLandscapeRight;
}
0
robegamesios