Force landscape orientation for UIWebView? - ios

I have an app where all the views are portraits but only one view which is a UIWebView which loads a PDF needs to be in Landscape.
My project settings are below:
I have tried the following:
override func shouldAutorotate() -> Bool {
return false
}
override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
let orientation: UIInterfaceOrientationMask = [UIInterfaceOrientationMask.Landscape, UIInterfaceOrientationMask.LandscapeLeft]
return orientation
}
The above code does not seem to be working. I got the code by searching online. I am not sure what I am doing wrong. Any suggestions would be help and if you can provide some sample code would be great.
I just want to force landscape orientation for one UIWebView.
EDIT:
Error:
If its hard to read here is the error:
Supported orientations has no common orientation with the application, and [KM_T_World.MainViewController shouldAutorotate] is returning YES'

Implement this in your View Controller:
override func viewDidLoad() {
super.viewDidLoad()
UIViewController.attemptRotationToDeviceOrientation()
}
override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
return [UIInterfaceOrientationMask.LandscapeLeft, UIInterfaceOrientationMask.LandscapeRight]
}

Use this code:
override func viewDidAppear(animated: Bool) {
let value = UIInterfaceOrientation.LandscapeLeft.rawValue
UIDevice.currentDevice().setValue(value, forKey: "orientation")
}
And your Device orientation should be:
Result:
Sample for more Info.
UPDATE:
It is simple to lock orientation for particular view by adding this code:
override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask{
return UIInterfaceOrientationMask.Portrait
}

Related

iOS Allow different screen orientation withouth autorotation

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.

Lock orientation in single Swift VC with Objective C AppDelegate

I've got an Objetive-C app delegate that is part of a project I'm interfacing with my own. I'm attempting to lock orientation, but it looks like the old methods (below) no longer work. Setting the orientation in viewDidLoad rotates the screen but allows the user to rotate back to portrait. I've attempted converting to "override var" but no luck. The current solutions (link below) look to all involve an app delegate call, but I cannot locate the solution for a Swift call to an Objective C app delegate.
How to lock orientation of one view controller to portrait mode only in Swift
override func shouldAutorotate() -> Bool {
return false
}
override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
return UIInterfaceOrientationMask.landscapeRight
}
To force only one controller to be at landscape orientation.
Manager:
class OrientationManager {
static let shared = OrientationManager()
/// you can set any orientation to lock
var orientationLock = UIInterfaceOrientationMask.portrait
/// lock orientation and force to rotate device
func lock(for orientation: UIInterfaceOrientationMask, rotateTo rotateOrientation: UIInterfaceOrientation) {
orientationLock = orientation
UIDevice.current.setValue(rotateOrientation.rawValue, forKey: "orientation")
}
}
Usage:
1) Add code to AppDelegate
func application(_ application: UIApplication,
supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
return OrientationManager.shared.orientationLock
}
2) Use in controller
open class LandscapeController: UIViewController {
/// orientation for one controller
override open func viewDidLoad() {
super.viewDidLoad()
OrientationManager.shared.lock(for: .landscape, rotateTo: .landscapeLeft)
}
/// set previous state of orientation or any new one
override open func viewWillDisappear(_ animated : Bool) {
super.viewWillDisappear(animated)
OrientationManager.shared.lock(for: .portrait, rotateTo: .portrait)
}
}
Solved my problem using this link, after trying just about everything.
how to lock portrait orientation for only main view using swift
I utilized the answer from JasonJasonJason and updated the code to get rid of the ->.
The below code went in my first VC
extension UINavigationController {
override open var shouldAutorotate: Bool {
return true
}
override open var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return (visibleViewController?.supportedInterfaceOrientations)!
}
}
Then subsequent VCs
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return UIInterfaceOrientationMask.landscape
}
Then since I had a TabBarController, I added this to the controller that pushes to the tab view. If you try to re-use the initial UINavigationController extension it won't let you, but the TabBarController ignores it. So the below extension solves it for any VC's with the TabBar
extension UITabBarController {
override open var shouldAutorotate: Bool {
return true
}
override open var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return UIInterfaceOrientationMask.landscape
}
}
For xcode 8.x & swift 3.x
We can control device orientation for particular screen.
On AppDelegate.swift make a variable enableAllOrientation:
var enableAllOrientation = false
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
if (enableAllOrientation == true){
return UIInterfaceOrientationMask.all
}
return UIInterfaceOrientationMask.portrait
}
& mask for particular view controller as -
override func viewWillAppear(_ animated: Bool)
{
super.viewWillAppear(animated)
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.enableAllOrientation = false
}

Unable to force UIViewController orientation

I have a portrait application with one landscape ViewController.
I've been digging a lot on how to force the orientation to landscape when the app is locked to portrait and I tried a lot of solutions presented here and not only but without any luck so far.
So far I managed to autorotate the VC I need in landscape but since the orientation is not locked, all other VCs will also rotate.
override func viewDidAppear(animated: Bool)
{
let value = UIInterfaceOrientation.LandscapeRight.rawValue
UIDevice.currentDevice().setValue(value, forKey: "orientation")
}
override func shouldAutorotate() -> Bool
{
return true
}
After some more digging I ended up with this after finding a sample project but while it works in that project, it doesn't seem to work for me.
This is in AppDelegate
func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> UIInterfaceOrientationMask {
if self.window?.rootViewController?.presentedViewController is ConclusionReferencesVC {
let conclusionReferencesVC = self.window!.rootViewController!.presentedViewController as! ConclusionReferencesVC
if conclusionReferencesVC.isPresented
{
return UIInterfaceOrientationMask.LandscapeRight;
}
else
{
return UIInterfaceOrientationMask.Portrait;
}
}
else
{
return UIInterfaceOrientationMask.Portrait;
}
}
This is in the VC I want to have in landscape:
var isPresented = true
#IBAction
func dismiss()
{
isPresented = false
self.presentingViewController!.dismissViewControllerAnimated(true, completion: nil);
}
For some reason, the supportedInterfaceOrientationsForWindow method does not validate the initial condition.
I also tried these among others but no luck:
How to lock orientation of one view controller to portrait mode only in Swift
supportedInterfaceOrientationsForWindow in Swift 2.0
Any ideas? It seems I'm missing something but I can't figure it out what.
try this for force to LandscapeRight mode only
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
if(self.supportedInterfaceOrientations() == UIInterfaceOrientationMask.LandscapeRight && UIDevice.currentDevice().orientation != UIDeviceOrientation.LandscapeRight)
{
let value = UIInterfaceOrientation.LandscapeRight.rawValue
UIDevice.currentDevice().setValue(value, forKey: "orientation")
}
}
and then use a category like this
import UIKit
extension UINavigationController{
override public func shouldAutorotate() -> Bool
{
return (self.viewControllers.last?.shouldAutorotate())!
}
override public func supportedInterfaceOrientations() ->UIInterfaceOrientationMask
{
return (self.viewControllers.last?.supportedInterfaceOrientations())!;
}
override public func preferredInterfaceOrientationForPresentation()-> UIInterfaceOrientation
{
return (self.viewControllers.last?.preferredInterfaceOrientationForPresentation())!;
}
}
EDITED
If you are not using navigation controller use this
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
if(self.supportedInterfaceOrientations() == UIInterfaceOrientationMask.LandscapeRight && UIDevice.currentDevice().orientation != UIDeviceOrientation.LandscapeRight)
{
let value = UIInterfaceOrientation.LandscapeRight.rawValue
UIDevice.currentDevice().setValue(value, forKey: "orientation")
}
}
override func supportedInterfaceOrientations() ->UIInterfaceOrientationMask
{
return .LandscapeRight;
}
I hope this helps you
As an update to Reinier Melian's post, here is the UINavigationController extension in Swift 3:
import UIKit
extension UINavigationController {
override open var shouldAutorotate: Bool {
return (self.viewControllers.last?.shouldAutorotate)!
}
override open var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return (self.viewControllers.last?.supportedInterfaceOrientations)!
}
override open var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
return (self.viewControllers.last?.preferredInterfaceOrientationForPresentation)!
}
}
Unfortunately, this code crashes if you call a UIImagePickerController, as that is contained within a UINavigationController whose last view controller is nil.
probably I´m crazy ;-), but why don´t u use this?

How I lock rotation on a UIViewController presented as modal form sheet?

I'm presenting a UIViewController modally with presentation style as Form Sheet, and it's not locking orientation when it appears as a form sheet. The form sheet modal presentation style looks different when shown on the iPhone 6+ in landscape, or on the iPad in any rotation.
I'm presenting the VC via a storyboard segue
This same code works correctly in locking orientation on iPhone (except 6+), but does not work when style is form sheet. How can I lock a modal form sheet in portrait on iPad or iPhone 6+?
override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
return .Portrait
}
override func shouldAutorotate() -> Bool {
return false
}
override func preferredInterfaceOrientationForPresentation() -> UIInterfaceOrientation {
return .Portrait
}
this code works for me, hope it works for u too
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let val = UIInterfaceOrientation.Portrait;
UIDevice .currentDevice() .setValue(val, forKey: "orientation");
}
override func shouldAutorotateToInterfaceOrientation(toInterfaceOrientation: UIInterfaceOrientation) -> Bool {
return (toInterfaceOrientation == UIInterfaceOrientation.Portrait)
}
override func shouldAutorotate() -> Bool {
return false
}

Upside down orientation in iPhone app using Swift

I am developing an app and intend to use upside down orientation in it. I have used the following code
override func willRotateToInterfaceOrientation(toInterfaceOrientation: UIInterfaceOrientation, duration: NSTimeInterval) {
if toInterfaceOrientation == UIInterfaceOrientation.PortraitUpsideDown {
self.shouldAutorotate()
}
}
But its not working. Any help!???
Device orientation (General Tab):
[x] Portrait
[x] Upside Down
[ ] Landscape Left
[ ] Landscape Right
Swift 2
// UINavigationController+UpsideDownOrientation.swift
import UIKit
extension UINavigationController {
public override func shouldAutorotate() -> Bool {
return true
}
public override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
return [.Portrait, .PortraitUpsideDown]
}
}
Try to put this on your plist file
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
</array>
And also verify on your target on general tab on Deployment info to have this:
On the other hand, are you using Navigation controller or Tab controller? If so, you will need to subclass navigation or tab controllers and add these two methods:
override func shouldAutorotate() -> Bool {
return true
}
override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
return UIInterfaceOrientationMask.All
}
Add this in your view controller code.
override func supportedInterfaceOrientations() -> Int{
return Int(UIInterfaceOrientationMask.All.rawValue)
}
Add this code on your Class or ViewController.
override func shouldAutorotate() -> Bool {
return false
}
override func supportedInterfaceOrientations() -> Int {
return UIInterfaceOrientation.Portrait.rawValue
}
Add these two functions to the viewcontrollers that you want to set the orientation to. Works for Swift 3.0 because I'm using it right now.
On your project, under General, select the "Device Orientation" that you want the App to support. Then go to the .plist and edit the Supported interface orientations (iPad) for the orientation you want to support.
override var shouldAutorotate: Bool {
return true
}
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return .landscapeRight // or .landscapeLeft or .portrait or .portraitUpsideDown which ever orientation you want the viewcontroller to be
}
1) Check your info.plist for Supported interface orientations, set it as you wish
2) Check your deployment information and select your chosen device orientations

Resources