Rotate screen in iOS
Rotate screen in iOS
In general, screen rotation can be controlled in either app level or viewcontroller level.
- App level control level is greater than viewcontroller level.
- For app level, two ways can be set up rotations, one is in the .plist, the other is in AppDelegate.
App level
plist
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationPortrait</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~iphone</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
AppDelegate
// Example: In iPhone device, we need only one viewcontrollers (DetailInfoViewController) can rotate to both portrait and landscape except upsidedown orientation. For the other viewcontrollers only allow one one orientation portrait. In iPad device, allow all rotation except for upside down.
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
if UIDevice.current.userInterfaceIdiom == .phone {
guard let allVC = application.keyWindow?.rootViewController?.childViewControllers else {
return UIInterfaceOrientationMask.portrait
}
guard let topVC = allVC.last else {
return UIInterfaceOrientationMask.portrait
}
if topVC is DetailInfoViewController {
return UIInterfaceOrientationMask.allButUpsideDown
} else {
return UIInterfaceOrientationMask.portrait
}
} else {
return UIInterfaceOrientationMask.allButUpsideDown
}
}
ViewController
Check current screen orientation
WARNINGS: Issues of relying on UIDevice.current.orientation.isPortrait
to detect device orientation
When device is put on the table, UIDevice.current.orientation.isPortrait
and UIDevice.current.orientation.isLandscape
both return false, UIDevice.current.orientation.isFlat
is return true. In this case, we better use UIApplication.shared.statusBarOrientation
to detect device orientation
Force to rotate the screen
// force to rotate to portrait
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
// force to portrait
if (UIApplication.shared.statusBarOrientation == .landscapeLeft || UIApplication.shared.statusBarOrientation == .landscapeRight) {
let value = UIInterfaceOrientation.landscapeLeft.rawValue
UIDevice.current.setValue(value, forKey: "orientation")
}
}
Do something when doing rotation
override func willTransition(to newCollection: UITraitCollection, with coordinator: UIViewControllerTransitionCoordinator) {
coordinator.animate(alongsideTransition: { (_) in
if UIApplication.shared.statusBarOrientation == .landscapeLeft || UIApplication.shared.statusBarOrientation == .landscapeRight {
print("do something when from Portrait to Landscape")
} else {
print("do something whenfrom Landscape to Portrait")
}
}, completion: { (UIViewControllerTransitionCoordinatorContext) -> Void in
print("rotation completed")
})
super.willTransition(to: newCollection, with: coordinator)
}