10

I'm using

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

to force the presenting view controller to show in landscape right. This is part of a navigation controller flow. This works as expected, but if the phone is held in landscape and titled between 45 and 90 degrees the view will present in portrait. The method is called and the expected value is correct, but no change to landscape occurs. This can be reproduced in a bare bones project with a navigation controller.

Does anyone have any idea what might cause this behavior?

Eric Aya
  • 69,473
  • 35
  • 181
  • 253
R.P. Carson
  • 439
  • 5
  • 20

3 Answers3

4

I also had this weird issue that when you rotate your device to the orientation you want to change when entering the next view controller then the screen stays in portrait mode. I managed to solve this issue by calling

UINavigationController.attemptRotationToDeviceOrientation()

after

UIDevice.current.setValue(value, forKey: "orientation")

was called. I guess this will only work if you're using UINavigationController.

Hunor Gocz
  • 137
  • 12
1

You could override

func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?)

as described in https://developer.apple.com/reference/uikit/uitraitenvironment/1623516-traitcollectiondidchange

as in

- (void) traitCollectionDidChange: (UITraitCollection *) previousTraitCollection {
    [super traitCollectionDidChange: previousTraitCollection];
    if ((self.traitCollection.verticalSizeClass != previousTraitCollection.verticalSizeClass)
        || (self.traitCollection.horizontalSizeClass != previousTraitCollection.horizontalSizeClass)) {
        // your custom implementation here
    }
}

to maintain your orientation as desired. Alternatively, in XCode, click on your target, choose the General tab, and choose only one allowed orientation.

mikep
  • 3,841
  • 8
  • 21
  • traitCollectionDidChange is called when something changes. the problem here is that nothing changes. the expected transition to landscape does not occur. – R.P. Carson Jun 02 '17 at 17:43
  • Hasn't the orientation changed and the change resulted in landscape to portrait, or did I misread the question? – mikep Jun 02 '17 at 17:56
  • issue seems to be that when phone is held a certain angle, the orientation does not change to landscape even when supposedly "forced" to change with setValue – R.P. Carson Jun 02 '17 at 18:26
1

Try this:

open override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    get {
        return UIInterfaceOrientationMask.landscapeRight
    }
}

open override var shouldAutorotate: Bool {
    get {
        return false
    }
}

open override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
    get {
        return UIInterfaceOrientation.landscapeRight
    }
}

From @Dragos answer on Setting device orientation in Swift iOS

elGeekalpha
  • 1,826
  • 3
  • 13
  • 14