How to change Device Orientation programmatically in Swift?
For each VC declare this variable w/ desired orientation. This is for portrait.
override var supportedInterfaceOrientations: UIInterfaceOrientationMask { return .portrait }
Then on appearance enforce the desired orientation.
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
UIView.setAnimationsEnabled(false)
UIDevice.current.setValue(UIInterfaceOrientation.portrait.rawValue, forKey: "orientation")
UIView.setAnimationsEnabled(true)
}
Change orientation programmatically with button - iOS
I don't have a swift code. Below are the objective c
code, It worked for me. You can convert it into swift as per your requirement.
Ojective C
UIInterfaceOrientation currentOrientation = [UIApplication sharedApplication].statusBarOrientation;
NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationPortrait];
[[UIDevice currentDevice] setValue:value forKey:@"orientation"];
[UIViewController attemptRotationToDeviceOrientation];
Update
Swift 4.0
var value = UIInterfaceOrientation.landscapeRight.rawValue
if UIApplication.shared.statusBarOrientation == .landscapeLeft || UIApplication.shared.statusBarOrientation == .landscapeRight{
value = UIInterfaceOrientation.portrait.rawValue
}
UIDevice.current.setValue(value, forKey: "orientation")
UIViewController.attemptRotationToDeviceOrientation()
Above code already tested by me and it is working fine. Incase above code is not worked for you, Then execute it after some delay using performSelector
.
iOS Swift 5 Change device orientation manually
One simple way to accomplish this is by setting your supported orientation on the AppDelegate
(_:supportedInterfaceOrientationsFor:)
Create a local variable there
var orientation: UIInterfaceOrientationMask = .portrait
and then return that variable as supported orientation
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
return orientation
}
on the ViewController
that you want to rotate with a touch of a button, you can change the supported orientation on the app delegate and than force the device orientation to change so that the view is rotated
private func changeSupportedOrientation() {
let delegate = UIApplication.shared.delegate as! AppDelegate
switch delegate.orientation {
case .portrait:
delegate.orientation = .landscapeLeft
default:
delegate.orientation = .portrait
}
}
@IBAction func rotateButtonTapped(_ sender: UIButton) {
changeSupportedOrientation()
switch UIDevice.current.orientation {
case .landscapeLeft:
UIDevice.current.setValue(UIDeviceOrientation.portrait.rawValue, forKey: "orientation")
default:
UIDevice.current.setValue(UIDeviceOrientation.landscapeLeft.rawValue, forKey: "orientation")
}
}
this will force the orientation of the device to change and then rotate your view. If you tap on the button again the orientation will be back to .portrait
Please be careful of using this as you need to really consider your navigation stack to make sure that only the top of the navigation stack support rotation and can only be pop from the navigation stack after the orientation is set back to the original which is .portrait
only.
How to change the device orientation programmatically and screen's rotation direction should be in clock wise direction
Each orientation in iOS has a raw value.
- portrait = 1
- portraitUpsideDown = 2
- landscapeLeft = 3
- landscapeRight = 4
You can change orientation based on these values.
Here is how I have done it in swift
Rotate in clockwise direction:
@IBAction func rotateClockwise(_ sender: Any) {
let orientation = UIDevice.current.orientation
print("Current state:",orientation.rawValue)
var newOrientation: Int {
switch orientation.rawValue {
case 1:
return 3
case 2:
return 4
case 3:
return 2
case 4:
return 1
default:
return 1
}
}
UIDevice.current.setValue(newOrientation, forKey: "orientation")}
Rotate in anti clockwise direction:
@IBAction func rotateAntiClockwise(_ sender: Any) {
let orientation = UIDevice.current.orientation
print("Current state:",orientation.rawValue)
var newOrientation: Int {
switch orientation.rawValue {
case 1:
return 4
case 2:
return 3
case 3:
return 1
case 4:
return 2
default:
return 1
}
}
UIDevice.current.setValue(newOrientation, forKey: "orientation")
}
Note
Make sure to select all orientations in target - general
If that doesn't work add the following code to view controller class
override var supportedInterfaceOrientations: UIInterfaceOrientationMask { get { return .all } }
Programmatic constraints with screen rotation (swift)
It is important to remember that we should be working with size layouts, rather than portrait / landscape. With multitasking slide over / split views, it's not unusual to have your view have a different height:width ratio than the device itself.
There are various ways to handle this... here's one approach.
- create an array of "wide layout" constraints
- create an array of "narrow layout" constraints
- create an array of "common" constraints - these apply whether in narrow or wide "orientation"
- activate / deactivate the wide and narrow constraints, based on the size of the view
Try this example:
class ChildView1: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
func commonInit() -> Void {
backgroundColor = .blue
layer.cornerRadius = 16
}
}
class ChildView2: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
func commonInit() -> Void {
backgroundColor = .red
layer.cornerRadius = 16
}
}
class SampleViewController: UIViewController {
let cv1 = ChildView1()
let cv2 = ChildView2()
// array of constraints for "wide" layout
var wideConstraints: [NSLayoutConstraint] = []
// array of constraints for "narrow" layout
var narrowConstraints: [NSLayoutConstraint] = []
// just for clarity, array of constraints that apply for
// both wide and narrow layouts
var commonConstraints: [NSLayoutConstraint] = []
override func viewDidLoad() {
super.viewDidLoad()
cv1.translatesAutoresizingMaskIntoConstraints = false
cv2.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(cv1)
view.addSubview(cv2)
let g = view.safeAreaLayoutGuide
commonConstraints = [
// cv1 will always be constrained top and leading
cv1.topAnchor.constraint(equalTo: g.topAnchor),
cv1.leadingAnchor.constraint(equalTo: g.leadingAnchor),
// cv2 will always be constrained trailing and bottom
cv2.trailingAnchor.constraint(equalTo: g.trailingAnchor),
cv2.bottomAnchor.constraint(equalTo: g.bottomAnchor),
]
// when narrow, cv1 on top of cv2
narrowConstraints = [
// constrain cv1 trailing
cv1.trailingAnchor.constraint(equalTo: g.trailingAnchor),
// constrain cv2 leading
cv2.leadingAnchor.constraint(equalTo: g.leadingAnchor),
// constrain cv2 top to cv1 bottom
cv2.topAnchor.constraint(equalTo: cv1.bottomAnchor),
// make them equal heights
cv2.heightAnchor.constraint(equalTo: cv1.heightAnchor),
]
// when wide, cv1 side-by-side cv2
wideConstraints = [
// constrain cv1 bottom
cv1.bottomAnchor.constraint(equalTo: g.bottomAnchor),
// constrain cv2 top
cv2.topAnchor.constraint(equalTo: g.topAnchor),
// constrain cv2 leading to cv1 trailing
cv2.leadingAnchor.constraint(equalTo: cv1.trailingAnchor),
// make them equal widths
cv2.widthAnchor.constraint(equalTo: cv1.widthAnchor),
]
// activate the commonConstraints
NSLayoutConstraint.activate(commonConstraints)
if view.frame.width > view.frame.height {
// wider than tall, so "landscape"
NSLayoutConstraint.activate(wideConstraints)
} else {
// taller than wide
NSLayoutConstraint.activate(narrowConstraints)
}
}
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
coordinator.animate(alongsideTransition: { _ in
if size.width > size.height {
// we're transitioning to wider than tall
NSLayoutConstraint.deactivate(self.narrowConstraints)
NSLayoutConstraint.activate(self.wideConstraints)
} else {
// we're transitioning to taller than wide
NSLayoutConstraint.deactivate(self.wideConstraints)
NSLayoutConstraint.activate(self.narrowConstraints)
}
}, completion: {
_ in
// if you want to do somwthing after the transition
})
}
}
iPad orientation programmatically not working
When you set programmatically the orientation of the device. To perform the orientation animation the function
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask
from AppDelegate
is being called.
If you have set it there to return only UIInterfaceOrientationMask.portrait
you will never see the transition.
Also I personally have these kind of problems and to solve this I had to programmaticaly force the phone to rotate to the current Orientation and then to rotate to the wanted orientation.
Example for phone to rotate landscapeLeft from portrait
func setOrientationToLandScapeOnly() {
appDelegate.shouldForceLandscapeOnly = true
appDelegate.shouldForcePortraitOnly = false
if UIDevice.current.userInterfaceIdiom == .phone {
switch UIApplication.shared.statusBarOrientation {
case .landscapeLeft, .landscapeRight:
return
default:
APIOrientationHandler.shared.setDeviceValueForOrientation(UIInterfaceOrientation.portrait.rawValue)
APIOrientationHandler.shared.setDeviceValueForOrientation(UIInterfaceOrientation.landscapeLeft.rawValue)
return
}
}
}
And inside AppDelegate.swift
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
if shouldForcePortraitOnly {
return UIInterfaceOrientationMask.portrait
}
if shouldForceLandscapeOnly {
return UIInterfaceOrientationMask.landscape
}
if (UIDevice.current.userInterfaceIdiom == UIUserInterfaceIdiom.pad) {
return UIInterfaceOrientationMask.landscape
}
return UIInterfaceOrientationMask.portrait
}
Related Topics
Formatting a Uitextfield for Credit Card Input Like (Xxxx Xxxx Xxxx Xxxx)
How to Keep Uitableview Contentoffset After Calling -Reloaddata
How to Put an Image in a Realm Database
Filemanager Cannot Find Audio File
Launch Apple Mail App from Within My Own App
How to Programmatically Fake a Touch Event to a Uibutton
Customize Mkannotation Callout View
How to Send a Silent Push Notification Payload
Replacement for Stringbyaddingpercentescapesusingencoding in iOS9
Change the iOS Keyboard Layout to Emoji
What Does "@Private" Mean in Objective-C
How to Implement Lazy Loading of Images in Table View Using Swift
iOS 8 - Buttons in Horizontal Scroll View Intercepting Pan Event - Scroll Does Not Work
Rotation Methods Deprecated, Equivalent of 'Didrotatefrominterfaceorientation'