I have 2 viewcontrollers (A & B).
A is auto rotation and B is force to landscape.
When user turn off Portrait Orientation Lock, it's work ok : A always rotation follow device orientation.
But when Portrait Orientation Lock is on, A's orientation is always landscape when it is returned from B.
How to force A is always portrait when Portrait Orientation Lock is enable.
Thanks.
Here - https://stackoverflow.com/a/41811798/10261915 You have answer
Add this to AppDelegate
struct AppUtility {
static func lockOrientation(_ orientation: UIInterfaceOrientationMask) {
if let delegate = UIApplication.shared.delegate as? AppDelegate {
delegate.orientationLock = orientation
}
}
/// OPTIONAL Added method to adjust lock and rotate to the desired orientation
static func lockOrientation(_ orientation: UIInterfaceOrientationMask, andRotateTo rotateOrientation:UIInterfaceOrientation) {
self.lockOrientation(orientation)
UIDevice.current.setValue(rotateOrientation.rawValue, forKey: "orientation")
UINavigationController.attemptRotationToDeviceOrientation()
}
}
and use for example
AppUtility.lockOrientation(.portrait, andRotateTo: .portrait)
add to BViewController :
override func viewDidLoad() {
super.viewDidLoad()
UIDevice.current.setValue(Int(UIInterfaceOrientation.landscapeLeft.rawValue), forKey: "orientation")
}
override func viewWillDisappear(_ animated: Bool) {
UIDevice.current.setValue(Int(UIInterfaceOrientation.portrait.rawValue), forKey: "orientation")
}
Related
I'm currently adapting an iphone app to ipad and have implemented the following code in the viewController to maintain one of the views in landscape (the other views are in portrait):
override func viewDidLoad() {
super.viewDidLoad()
collectionView.dataSource = self
collectionView.delegate = self
//TODO: - Keep presentationView in landscape
let value = UIInterfaceOrientation.landscapeLeft.rawValue
UIDevice.current.setValue(value, forKey: "orientation")
}
override func viewDidDisappear(_ animated: Bool) {
let value = UIInterfaceOrientation.portrait.rawValue
UIDevice.current.setValue(value, forKey: "orientation")
}
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return .landscapeLeft
}
override var shouldAutorotate: Bool {
return true
}
This works fine for the iphone but does not work when displaying the app on iPad i.e. the view rotates and can be seen in both portrait and landscape. Be grateful for any suggestions on how I can adapt the code to make it work on iPad.
Add method viewWillTransition(to:with:).
Notifies the container that the size of its view is about to change.UIKit calls this method before changing the size of a presented view controller’s view. You can override this method in your own objects and use it to perform additional tasks related to the size change.
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
if UIDevice.current.orientation.isLandscape {
print("Landscape")
// Update frame
} else {
print("Portrait")
// Update frame
}
}
I am trying to make just one view of the landscape and other all views are on the portrait. It works but there is an issue on every second-time screen doesn't rotate at all.
Here is the scenario that I am talking about:
On every second time, device rotation doesn't work.
Here is my code
AppDelegate.swift
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
return .portrait
}
Controller1.swift
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return .portrait
}
override var shouldAutorotate: Bool {
return true
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
AppUtility.lockOrientation(.portrait)
}
DetailController.swift
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
AppUtility.lockOrientation(.landscape, andRotateTo: .landscapeLeft)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
if isMovingFromParentViewController {
AppUtility.lockOrientation(.portrait, andRotateTo: .portrait)
}
}
Code that effects the rotation
struct AppUtility {
static func lockOrientation(_ orientation: UIInterfaceOrientationMask) {
if let delegate = UIApplication.shared.delegate as? AppDelegate {
delegate.orientationLock = orientation
}
}
static func lockOrientation(_ orientation: UIInterfaceOrientationMask, andRotateTo rotateOrientation:UIInterfaceOrientation) {
self.lockOrientation(orientation)
UIDevice.current.setValue(rotateOrientation.rawValue, forKey: "orientation")
}
}
So, How to force rotate detail view every time it loads?
Step 1:- Please define a below-mentioned variable in app delegate.
var shouldRotate : Bool = false
Step 2:- Implement the following delegate method as below.
//MARK:- Set Device Orientation Delegate Method
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
return shouldRotate ? .landscapeRight : .portrait
}
Step 3 :- Define constant class and add "Set Portrait Orientation" and "Set Landscape Right Orientation" function in the class.
//MARK:- Set Portrait Orientation
func setPortraitOrientation() {
appDelegateInstance.shouldRotate = false
UIDevice.current.setValue(UIInterfaceOrientation.portrait.rawValue, forKey: "orientation")
}
//MARK:- Set Landscape Right Orientation
func setLandscapeRightOrientation() {
appDelegateInstance.shouldRotate = true
UIDevice.current.setValue(UIInterfaceOrientation.landscapeRight.rawValue, forKey: "orientation")
}
Step 4:- Use the following code in your class (Target landscape class)
Step 4.1:- In view will appear call set Landscape Right Orientation function shown below.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
setLandscapeRightOrientation()
}
Step 4.2 :- When you leave the screen implement the following code in the action.
//MARK:- Left Bar Button Tapped Delegate Method
func leftBarButtonTapped() {
_ = self.navigationController?.popViewController(animated: false)
setPortraitOrientation()
}
Happy Coding! Cheers!!
i did change orientation of uidevice as per screen requirement.
For example screen A
Which i need to make portrait only.
Screen B
It should be landscape and i did it.
But after going back to screen A and again i go to screen B and rotate device left to right or right to left screen B's orientation changes to portrait.
Please comment if anyone have solution for this.
Here i will explain whole scenario what i am doing in my project:
AppDelegate.swift
var orientationLock = UIInterfaceOrientationMask.portrait //Defined variable for orientation
func application(_ application: UIApplication,
supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
return shouldRotate ? .allButUpsideDown : .portrait
}
In class A
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let value = UIInterfaceOrientation.portrait.rawValue
UIDevice.current.setValue(value, forKey: "orientation")
Global.appDelegate.shouldRotate = false
}
In class B
DispatchQueue.main.async {
let value = UIInterfaceOrientation.landscapeLeft.rawValue
UIDevice.current.setValue(value, forKey: "orientation")
}
Global.appDelegate.shouldRotate = false
Now i tried to make B screen landscape in all rotation, for that i tried method below:
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
coordinator.animate(alongsideTransition: nil, completion: {
_ in
if UIDevice.current.orientation == .portrait || UIDevice.current.orientation == .portraitUpsideDown {
// Global.AppUtility.lockOrientation(.landscape)
let value = UIInterfaceOrientation.landscapeLeft.rawValue
UIDevice.current.setValue(value, forKey: "orientation")
Global.appDelegate.shouldRotate = true
}
})
}
But this method works first time only, after selecting A and again i go to screen B it keep it portrait.
I want to keep a portrait orientation even if user rotate the phone. At the same time, I want to change the orientation with a button.
If I put only portrait as supported orientation in plist and then rotate, application gives me error. If I put all the supported orientation but shouldAutorotate method to NO, Application crashes.
So, basically as I can see I can only support multiple orientation if I let the application to autorotate.
Can I achieve what I need?
shouldAutorotate
this is a get-only property.
what you can do is:
override var shouldAutorotate: Bool {
return false
}
Maybe this is also interesting for you: how to dissable and enable auto rotate on swift?
May be the following line of code will work for you. set orientation programmatically.
In your Appdelegate class write this code:
var orientationLock = UIInterfaceOrientationMask.all
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
return self.orientationLock
}
2.Make custom helper class as follows:
struct AppUtility {
static func lockOrientation(_ orientation: UIInterfaceOrientationMask) {
if let delegate = UIApplication.shared.delegate as? AppDelegate {
delegate.orientationLock = orientation
}
}
/// OPTIONAL Added method to adjust lock and rotate to the desired orientation
static func lockOrientation(_ orientation: UIInterfaceOrientationMask, andRotateTo rotateOrientation:UIInterfaceOrientation) {
self.lockOrientation(orientation)
UIDevice.current.setValue(rotateOrientation.rawValue, forKey: "orientation")
}
}
then use it in your desire viewcontroller like:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
AppUtility.lockOrientation(.portrait)
// Or to rotate and lock
// AppUtility.lockOrientation(.portrait, andRotateTo: .portrait)
}
override func viewWillDisappear(_ animated: Bool){
super.viewWillDisappear(animated)
// Don't forget to reset when view is being removed
AppUtility.lockOrientation(.all)
}
note: keep remember Require Full Screen option is checked from target settings.
I'd like to fix my Camera View in landscape Mode. And also show an alert when user rotate view to portrait. is there any solution available ?
Put this in your view controller:
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
if UIDevice.current.orientation.isLandscape {
print("will turn to landscape")
} else {
print("will turn to portrait")
//print an alert box here
UIDevice.current.setValue(UIInterfaceOrientation.landscapeLeft.rawValue, forKey: "orientation")
}
}
Source: How to detect orientation change?
Or put this to the view that needs to be in landscape:
override func shouldAutorotate() -> Bool {
return false
}
override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
return UIInterfaceOrientationMask.landscape
}
But this one cannot post an alert.