webentwicklung-frage-antwort-db.com.de

Wie kann ich die Geräteorientierung in iOS 7 programmgesteuert einstellen?

Ich arbeite an einer iPad-App mit AutoLayout. Wenn der Benutzer einen bestimmten Modus aktiviert ("Heads-Up" -Modus), möchte ich nur die Ausrichtung Hochformat (oder umgekehrt) unterstützen, und außerdem, wenn sich das Gerät im Gerät befindet Landschaft möchte ich automatisch in den Hochformatmodus wechseln.

In der Draufsichtsteuerung habe ich Folgendes:

- (NSUInteger) supportedInterfaceOrientations {
    if (self.modeHeadsUp) {
        return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown;
    } else {
        return UIInterfaceOrientationMaskAll;
    }
}

- (BOOL) shouldAutorotate {
    return TRUE;
}

Basierend auf Antworten, die ich hier an anderer Stelle gesehen habe, scheint die Antwort scheint zu sein, dass ich "application setStatusBarOrientation" verwenden sollte. Daher habe ich in der Methode, in der der Benutzer den Modus "Heads-Up" ausgewählt hat, Folgendes hinzugefügt:

    UIApplication *application = [UIApplication sharedApplication];
    [application setStatusBarOrientation:UIInterfaceOrientationPortrait
                                animated:YES];

Dies scheint jedoch einfach nichts zu tun. Ich kann das Gerät zwar physisch verschieben, um es in das Hochformat zu drehen, dies geschieht jedoch nicht automatisch.

Wenn Sie nach dem Ausführen des obigen Codes im Querformatmodus versuchen, die Ausrichtung programmgesteuert festzulegen, bleibt beim Abfragen der Anwendung "statusBarOrientation" mit folgendem Code die Landschaft "4": 

UIApplication *application = [UIApplication sharedApplication];
int orientation = [application statusBarOrientation];
self.movesTextView.text = [NSString stringWithFormat:@"ORIENTATION %d", orientation];

Es schien, als würde Autolayout möglicherweise nicht mit der setStatusBarOrientation ausgelöst werden. Ich habe also versucht, diesen Code nachträglich hinzuzufügen, ohne dass dies Auswirkungen hatte:

    [super updateViewConstraints];
    [self.view updateConstraints];

Mir ist klar, dass Apple die Geräteorientierung in den Händen des Benutzers belassen möchte. Ich möchte jedoch den Querformatmodus unterstützen, wenn Sie sich nicht im "Heads-Up" -Modus befinden. 

Vermisse ich etwas, um die Orientierungsänderung erzwingen zu können?

70
John Stewart

Für iOS 7 und 8:

Ziel c:

NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeLeft];
[[UIDevice currentDevice] setValue:value forKey:@"orientation"];

Swift 3+:

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

Ich nenne es in - viewDidAppear:.

194
Sunny Shah

Benutze das. Perfekte Lösung für das Orientierungsproblem..ios7 und früher

[[UIDevice currentDevice] setValue:
    [NSNumber numberWithInteger: UIInterfaceOrientationPortrait]
        forKey:@"orientation"];
20
Arpan Dixit

Sie müssen attemptRotationToDeviceOrientation (UIViewController) aufrufen, damit das System Ihre supportedInterfaceOrientations aufruft, wenn sich die Bedingung geändert hat.

10
snak
NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeLeft]; [[UIDevice currentDevice] setValue:value forKey:@"orientation"];

funktioniert, aber Sie müssen zurückkehren, sollten Sie mit YES in Ihrem View-Controller angeben

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

Wenn Sie das tun, wird Ihre VC sich automatisch drehen, wenn der Benutzer das Gerät dreht ... Daher habe ich es geändert in:

@property (nonatomic, assign) BOOL shouldAutoRotate;

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

und ich rufe an 

- (void)swithInterfaceOrientation:(UIInterfaceOrientation)orientation
{
    self.rootVC.shouldAutoRotate = YES;

    NSNumber *value = [NSNumber numberWithInt: orientation];
    [[UIDevice currentDevice] setValue:value forKey:@"orientation"];
}

um eine neue ausrichtung mit einem schaltknopf zu erzwingen. ____. Sollte autoRotate auf NO gesetzt werden, fügte ich meiner rootVC hinzu

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
    self.shouldAutoRotate = NO;
}

PS: Diese Problemumgehung funktioniert auch in allen Simulatoren.

4
Rikco

Dies funktioniert für mich bei Xcode 6 & 5.

- (BOOL)shouldAutorotate {
    return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
    return (UIInterfaceOrientationMaskPortrait);
}
4
SamSmart

Der einzige Weg, der für mich funktioniert hat, ist die Präsentation von Dummy-Modal-View-Controllern.

UIViewController* dummyVC = [[UIViewController alloc] init];
dummyVC.view = [[UIView alloc] init];
[self presentModalViewController:dummyVC animated:NO];
[self dismissModalViewControllerAnimated:NO];

Ihr VC wird nach aktualisierten Schnittstellenausrichtungen gefragt, wenn der Modal-View-Controller geschlossen wird.

Merkwürdig ist, dass UINavigationController genau dies tut, wenn untergeordnete Ansichtscontroller mit verschiedenen unterstützten Schnittstellenorientierungen (Push-to-Popping) auf iOS 6.1, 7.0 getestet werden.

3
kjam

Mit dieser Lösung können Sie eine bestimmte Schnittstellenorientierung erzwingen, indem Sie den Wert von UIDevice.current.orientation vorübergehend überschreiben und das System dann auffordern, die Schnittstelle entsprechend der Drehung des Geräts zu drehen:

Wichtig: Dies ist ein Hack und könnte jederzeit aufhören zu arbeiten

Fügen Sie im Root-View-Controller Ihrer App Folgendes hinzu:

class RootViewController : UIViewController {
    private var _interfaceOrientation: UIInterfaceOrientation = .portrait
    override var supportedInterfaceOrientations: UIInterfaceOrientationMask { return UIInterfaceOrientationMask(from: _interfaceOrientation) }
    override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation { return _interfaceOrientation }

    override func viewDidLoad() {
        super.viewDidLoad()
        // Register for notifications
        NotificationCenter.default.addObserver(self, selector: #selector(RootViewController.handleInterfaceOrientationChangeRequestedNotification(_:)), name: .interfaceOrientationChangeRequested, object: nil)
    }

    deinit { NotificationCenter.default.removeObserver(self) }

    func handleInterfaceOrientationChangeRequestedNotification(_ notification: Notification) {
        guard let interfaceOrientation = notification.object as? UIInterfaceOrientation else { return }
        _interfaceOrientation = interfaceOrientation
        // Set device orientation
        // Important:
        // • Passing a UIDeviceOrientation here doesn't work, but passing a UIInterfaceOrientation does
        // • This is a hack, and could stop working at any moment
        UIDevice.current.setValue(interfaceOrientation.rawValue, forKey: "orientation")
        // Rotate the interface to the device orientation we just set
        UIViewController.attemptRotationToDeviceOrientation()
    }
}

private extension UIInterfaceOrientationMask {

    init(from interfaceOrientation: UIInterfaceOrientation) {
        switch interfaceOrientation {
        case .portrait: self = .portrait
        case .landscapeLeft: self = .landscapeLeft
        case .landscapeRight: self = .landscapeRight
        case .portraitUpsideDown: self = .portraitUpsideDown
        case .unknown: self = .portrait
        }
    }
}

extension Notification.Name {
    static let interfaceOrientationChangeRequested = Notification.Name(rawValue: "interfaceOrientationChangeRequested")
}

Stellen Sie sicher, dass alle Schnittstellenausrichtungen unter "Bereitstellungsinformationen" überprüft werden:

 Interface Orientations

Fordern Sie Änderungen an der Benutzeroberfläche an, wenn Sie diese benötigen:

NotificationCenter.default.post(name: .interfaceOrientationChangeRequested, object: UIInterfaceOrientation.landscapeRight)
3
Niels
  1. Fügen Sie diese Anweisung in AppDelegate.h hinzu.

    //whether to allow cross screen marker 
    @property (nonatomic, assign) allowRotation BOOL;
    
  2. Schreiben Sie diesen Abschnitt in AppDelegate.m auf.

    - (UIInterfaceOrientationMask) application: (UIApplication *) supportedInterfaceOrientationsForWindow: application (UIWindow *) window {
        If (self.allowRotation) {
            UIInterfaceOrientationMaskAll return;
        }
        UIInterfaceOrientationMaskPortrait return;
    }
    
  3. Ändern Sie die allowRotation-Eigenschaft der Delegatenanwendung

2
niuNaruto

Wenn Sie einen UIViewController haben, der im Portrait-Modus bleiben soll, fügen Sie einfach diese Überschreibung hinzu und Sie sind fertig.

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

Das Beste daran ist, dass es keine Animation gibt, wenn diese Ansicht angezeigt wird. Sie befindet sich bereits in der richtigen Ausrichtung.

2
Torre Lasley

Wenn Sie die Hauptansicht Ihrer App für Hochformat sperren möchten, aber Popup-Ansichten in Querformat öffnen möchten und tabBarController als rootViewController verwenden, können Sie diesen Code in Ihrer AppDelegate verwenden.

AppDelegate.h

@interface AppDelegate : UIResponder <UIApplicationDelegate, UITabBarControllerDelegate>

@property (strong, nonatomic) UIWindow *window;
@property (strong, nonatomic) UITabBarController *tabBarController;

@end

AppDelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

    // Create a tab bar and set it as root view for the application
    self.tabBarController = [[UITabBarController alloc] init];
    self.tabBarController.delegate = self;
    self.window.rootViewController = self.tabBarController;

    ...
}

- (NSUInteger)tabBarControllerSupportedInterfaceOrientations:(UITabBarController *)tabBarController
{
    return UIInterfaceOrientationMaskPortrait;
}

- (UIInterfaceOrientation)tabBarControllerPreferredInterfaceOrientationForPresentation:(UITabBarController *)tabBarController
{
    return UIInterfaceOrientationPortrait;
}

Es funktioniert sehr gut.

In Ihrem viewController möchten Sie in Landschaft dargestellt werden, verwenden Sie einfach Folgendes:

- (NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskLandscape;
}

- (BOOL)shouldAutorotate {
    return YES;
}

Der Basis-UINavigationController sollte den folgenden Callback haben, damit die untergeordneten Elemente entscheiden können, welche Ausrichtung sie wünschen.

-(NSUInteger)supportedInterfaceOrientations {
    UIViewController *topVC = self.topViewController;
    return topVC.supportedInterfaceOrientations;
}

-(BOOL)shouldAutorotate {
   UIViewController *topVC = self.topViewController;
   return [topVC shouldAutorotate];
}
1
Ekra

hier ist ein VOLLSTÄNDIGES ARBEITEN-Beispiel für iOS 7, 8, 9, 10, wie Sie die Ausrichtung der App auf ihr aktuelles Gegenteil ändern

Ziel c

- (void)flipOrientation
{
    NSNumber *value;
    UIInterfaceOrientation currentOrientation = [[UIApplication sharedApplication] statusBarOrientation];
    if(UIInterfaceOrientationIsPortrait(currentOrientation))
    {
        if(currentOrientation == UIInterfaceOrientationPortrait)
        {
            value = [NSNumber numberWithInt:UIInterfaceOrientationPortraitUpsideDown];
        }
        else //if(currentOrientation == UIInterfaceOrientationPortraitUpsideDown)
        {
            value = [NSNumber numberWithInt:UIInterfaceOrientationPortrait];
        }
    }
    else
    {
        if(currentOrientation == UIInterfaceOrientationLandscapeRight)
        {
            value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeLeft];
        }
        else //if(currentOrientation == UIInterfaceOrientationLandscapeLeft)
        {
            value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeRight];
        }
    }
    [[UIDevice currentDevice] setValue:value forKey:@"orientation"];
    [UIViewController attemptRotationToDeviceOrientation];
}

Swift 3

func flipOrientation() -> Void
{
    let currentOrientation : UIInterfaceOrientation = UIApplication.shared.statusBarOrientation
    var value : Int = 0;
    if(UIInterfaceOrientationIsPortrait(currentOrientation))
    {
        if(currentOrientation == UIInterfaceOrientation.portrait)
        {
            value = UIInterfaceOrientation.portraitUpsideDown.rawValue
        }
        else //if(currentOrientation == UIInterfaceOrientation.portraitUpsideDown)
        {
            value = UIInterfaceOrientation.portrait.rawValue
        }
    }
    else
    {
        if(currentOrientation == UIInterfaceOrientation.landscapeRight)
        {
            value = UIInterfaceOrientation.landscapeLeft.rawValue
        }
        else //if(currentOrientation == UIInterfaceOrientation.landscapeLeft)
        {
            value = UIInterfaceOrientation.landscapeRight.rawValue
        }
    }
    UIDevice.current.setValue(value, forKey: "orientation")
    UIViewController.attemptRotationToDeviceOrientation()
}
1
ddb

Ich hatte ein ähnliches Problem wie Sie. Ich muss die Ausrichtung des Geräts für einige Bildschirme (wie Login) sperren und die Drehung in anderen zulassen.

Nach ein paar Änderungen und folgenden Antworten habe ich es gemacht:

  • Aktivieren Sie alle Ausrichtungen in der Info.plist des Projekts.

 enter image description here

  • Deaktivierung der Ausrichtung in den ViewControllern, bei denen das Gerät nicht gedreht werden muss, wie in meinem Anmeldebildschirm. Ich musste die shouldAutorotate-Methode in diesem VC überschreiben:

-(BOOL)shouldAutorotate{ return NO; }

Ich hoffe, das funktioniert für Sie.

1
David de Tena

Wenn Sie nur den Porträtmodus wünschen, können Sie in iOS 9 (Xcode 7) Folgendes tun: 

  • Gehe zur Info.plist
  • Wählen Sie den Punkt "Unterstützte Schnittstellenorientierungen"
  • Löschen Sie "Landscape (linke Home-Taste)" und "Landscape (rechte Home-Taste)".

 enter image description here

1
Danilo Raspa

Das hat mir perfekt geholfen ....

NSNumber *value = [NSNumber numberWithInt:UIDeviceOrientationPortrait];
[[UIDevice currentDevice] setValue:value forKey:@"orientation"];
0
Prasanna

Für diejenigen wie mich, die um @Sunny Shah kämpften, akzeptierte Antwort, um an iPads zu arbeiten. Sie müssen das Kontrollkästchen "Vollbild erforderlich" in den Projekteinstellungen aktivieren. Beachten Sie, dass dies Ihre App daran hindert, im Multitasking-Modus zu arbeiten, der möglicherweise akzeptabel ist oder nicht.

 enter image description here 

0
leandrodemarco

Versuchen Sie dies zusammen mit Ihrem Code.

-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation  

-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration

sobald der Benutzer eine Option auswählt, rufen Sie diese Methode auf, da sich der Benutzer im Querformat befinden kann. Dann kann er nur den Hochformatmodus in demselben Ansichtscontroller festlegen. Die Ansicht sollte daher automatisch in den Hochformatmodus verschoben werden

-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
0
Charan Giri