How to Change Device Orientation Programmatically in Swift

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.

  1. portrait = 1
  2. portraitUpsideDown = 2
  3. landscapeLeft = 3
  4. landscapeRight = 4

You can change orientation based on these values.

Here is how I have done it in swift

  1. 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")

    }

  2. 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 } }

How to update the UI when the device orientation changed in Swift?

Actually by using

loginView.frame = CGRect(origin: .zero, size: view.bounds.size)

you assign a frame to your login view which will not change on device rotation.

you might wanna use a constraint approach here as well:

// try replacing
// loginView.frame = CGRect(origin: .zero, size: view.bounds.size)

// with
loginView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
loginView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
loginView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
loginView.topAnchor.constraint(equalTo: view.topAnchor),
loginView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
])

Another approach would be updating the frame of your login view e.g.

override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
loginView.frame = CGRect(origin: .zero, size: view.bounds.size)
}

Last but not least you can use autoresizingMask in viewDidLoad

loginView.frame = CGRect(origin: .zero, size: view.bounds.size)
loginView.autoresizingMask = [.flexibleHeight, .flexibleWidth]

P.S. My previous comment was misleading since the login frame wasn't set in the setupStackView() function

and my final comment:

// you can replace
loginView.frame = CGRect(origin: .zero, size: view.bounds.size)
// with
loginView.frame = view.bounds


Related Topics



Leave a reply



Submit