Reputation: 6477
iOS 13/13.1 autorotation seems to be behave differently than iOS 12. For instance, my app allows user to lock interface orientation to portrait or landscape mode in settings.
If I have portrait rotation lock on device and return .landscape in supportedInterfaceOrientations, the interface remains in portrait mode until I disable portrait lock orientation on device. This does not seem to be the case with iOS 12. Infact, supportedInterfaceOrientations is not even called in iOS 13!
UIViewController.attemptRotationToDeviceOrientation() also does not work in such cases.
The root of the problem is I temporarily return shouldAutorotate to false while the app is initializing and when everything is initialized, I call UIViewController.attemptRotationToDeviceOrientation() to trigger autorotation. It triggers autorotation in iOS 12 but in iOS 13.1 it doesn't works.
Looks like a bug in iOS 13.1 probably. What do I do to force trigger autorotation?
EDIT: Looks like iOS 12.4.1 also ignores UIViewController.attemptRotationToDeviceOrientation(). There is something broken in autorotation in iOS 12.4.1 & above.
To be clear, this is what I want:
a. Even if portrait lock is set on iPhone, I wish my interface to autorotate to landscape mode if required,
b. UIViewController.attemptRotationToDeviceOrientation() alternative that triggers autorotation in all circumstances.
Upvotes: 16
Views: 5388
Reputation: 1
Replying for other people facing this issue, this is what worked for me. Go to the project settings General > Deployment Info and make sure you have checked "Requires full screen" setting.
Then paste the following code after the viewDidLoad block:
// Forbid autorotate
override open var shouldAutorotate: Bool {
return false
}
// Specify the orientation
override open var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return .landscape
}
Upvotes: 0
Reputation: 343
From iOS 12.4.1, View Controller should be set to Full Screen to respect the auto-rotate orientation.
let vc = UIViewController()
vc.modalPresentationStyle = .fullScreen
self.present(vc, animated: true, completion: nil)
Upvotes: 3
Reputation: 3439
Try this and see if this is something you are looking for:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
@IBAction func btnLandscapeClicked(_ sender: Any) {
let value = UIInterfaceOrientation.landscapeLeft.rawValue
UIDevice.current.setValue(value, forKey: "orientation")
}
@IBAction func btnPortraitClicked(_ sender: Any) {
let value = UIInterfaceOrientation.portrait.rawValue
UIDevice.current.setValue(value, forKey: "orientation")
}
}
extension UINavigationController {
override open var shouldAutorotate: Bool {
get {
if let visibleVC = visibleViewController {
return visibleVC.shouldAutorotate
}
return super.shouldAutorotate
}
}
override open var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation{
get {
if let visibleVC = visibleViewController {
return visibleVC.preferredInterfaceOrientationForPresentation
}
return super.preferredInterfaceOrientationForPresentation
}
}
override open var supportedInterfaceOrientations: UIInterfaceOrientationMask{
get {
if let visibleVC = visibleViewController {
return visibleVC.supportedInterfaceOrientations
}
return super.supportedInterfaceOrientations
}
}}
Upvotes: 0