Can you disable rotation globally in an iOS app? - ios

I have an app made up of a lot of view controllers... in the project summary I've set Portrait orientation as the only supported device orientation.
However, the app still gets messed up when turned sideways.
My question is, is there a way to globally disable autorotation through app delegate or something?
Or do I have to go into all of my view controllers and add the "shouldAutorotateToInterfaceOrientation" method?
Just don't want to miss adding it to one or something...
Thanks!

In Info.plist expand "Supported interface orientations" and remove Landscape items to make your application only run in portrait mode.

There are three kinds of Device orientation keys there in the info.plist now.
Supported interface orientations (iPad)
Supported interface orientations (iPhone)
Supported interface orientations
Third one is I think for non-universal apps and rest two above are for iPad and iPhone.
You should give them a try.

After struggling to set in UIViewController's shouldAutorotate and supportedInterfaceOrientation methods, with no success in iOS6, I found the most effective is to set it in app delegate.
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
return UIInterfaceOrientationMaskPortrait;
}
However returning UIInterfaceOrientationMaskPortraitUpsideDown was crashing my app. I dont know whats wrong I was doing!

in root view controller's method:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
set 'return NO';
this should do for all the Views.

If you're supporting iPad, then you SHOULD NOT uncheck the landscape orientations, as it will prevent your app from being accepted by Apple on App Store.
To prevent rotating before the app shows your first screen, put this inside your AppDelegate.m
This method works and tested in iOS 7.1 above.
// G - fix for ipad.
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
return UIInterfaceOrientationMaskPortrait;
}

Haris Hussain's answer appears to be deprecated now, as of IOS 6, but there are new methods available for limiting/enabling rotation.
Here are the methods listed in the UIViewController header:
// New Autorotation support.
- (BOOL)shouldAutorotate NS_AVAILABLE_IOS(6_0);
- (UIInterfaceOrientationMask)supportedInterfaceOrientations NS_AVAILABLE_IOS(6_0);
// Returns interface orientation masks.
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation NS_AVAILABLE_IOS(6_0);
Note that shouldAutoRotate doesn't seem to work if you start the app in an already rotated state!

Swift
iOS 6+
The recommended way is to override shouldAutorotate in every attached view controller. If you override this property in the root view controller, then all "attached" view controllers will also inherit the behavior. Presented view controllers, however, can become "unattached" to the root and thus would not inherit the override and so you would need to override the property in those view controllers separately.
class RootViewController: UIViewController {
override var shouldAutorotate: Bool { false }
}
class PresentedViewController: UIViewController {
override var shouldAutorotate: Bool { false }
}
However, if you simply subclass UIViewController and only use the subclassed view controllers in your project then you have a truly global fix (using code).
class NonrotatableViewController: UIViewController {
override var shouldAutorotate: Bool { false }
}
Settings alternative (no code)
Perhaps the most global fix is editing the Info.plist file in the info tab in the target's settings. There is a supported-interface-orientations key with each value representing a supported orientation. Deleting all but portrait will disable rotation in all view controllers, attached or unattached to the root.

Related

Keyboard appears in wrong orientation in ios

I have one viewcontroller in application that supports landscape and portrait orientations.
On a button click, a popup appears where I should enter the name. everything works as it should on portrait mode.
But if I dismiss the keyboard, rotate the device left or right and then open the popup, keyboard still opens in portrait mode.
I've shouldAutorotate returning true and supportedInterfaceOrientations returning AllButUpsideDown in viewcontroller, so rotation happens automatically.
I tried this and this options but none of them work.
Any ideas what to do?
I got exactly the same wrong keyboard orientation in some of my view controllers recently after I dropped support for iOS 8 and bumped up the deployment target to iOS 9. It turns out that one of my former colleagues used a solution here to solve an old problem when the base SDK was iOS 9 (we're now in 10, and 11 when coding from Xcode 9 beta). That solution (basically override UIAlertController's supportedInterfaceOrientations to only allow portrait) would force present the keyboard in portrait with newer SDK + deployment target even though the app window and the alert itself are in landscape.
Removing that override solved the problem and I don't see any issue with alert over alert.
Try by adding below code to your viewcontroller's viewDidAppear method
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[[UIDevice currentDevice] setValue:#(UIDeviceOrientationLandscapeLeft) forKey:#"orientation"];
[[UIDevice currentDevice] setValue:#(self.interfaceOrientation) forKey:#"orientation"];
}
Ok, fixed it, my fault I guess.
It seems Keyboard and UIViewController call supportedInterfaceOrientations separately and rotate based on its return value. I had an if-else statement in there and was returning AllButUpsideDown only in some cases. When keyboard checked whether it was supposed to rotate method returned Portrait, and for viewcontroller value was AllButUpsideDown.
So I changed this:
public override UIInterfaceOrientationMask GetSupportedInterfaceOrientations()
{
if (someStatement)
{
return UIInterfaceOrientationMask.AllButUpsideDown;
}
return UIInterfaceOrientationMask.Portrait;
}
To this:
public override UIInterfaceOrientationMask GetSupportedInterfaceOrientations()
{
return UIInterfaceOrientationMask.AllButUpsideDown;
}
And now only ShouldAutoRotate decides whether it rotation should happen or not.
To some up it should look like this:
public override bool ShouldAutorotate()
{
if (someStatement)
{
return true;
}
return false;
}
public override UIInterfaceOrientationMask GetSupportedInterfaceOrientations()
{
return UIInterfaceOrientationMask.AllButUpsideDown;
}
Create subclass of UIAlertController
MyAlertController.h //header file
#interface MyAlertController : UIAlertController
#end
MyAlertController.m
#implementation MyAlertController
- (BOOL)shouldAutorotate
{
return NO;
}
-(UIInterfaceOrientationMask)supportedInterfaceOrientations
{
[super supportedInterfaceOrientations];
return UIInterfaceOrientationMaskLandscape;
}
#end

iOS Error: Supported orientations has no common orientation with the application (iPhone)

Using iOS 8.3
I have a view in landscape mode, and i'm trying to open a portrait only view controller. every time i try to open it, the app crashes.
I have read this official apple answer which basically recommends doing the following:
in the app delegate:
#implementation AppDelegate
-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
return UIInterfaceOrientationMaskAll;
else /* iphone */
return UIInterfaceOrientationMaskAllButUpsideDown;
}
and in my controller:
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscape;
}
And so i have, and yet i still get this crash message:
Terminating app due to uncaught exception 'UIApplicationInvalidInterfaceOrientation', reason: 'Supported orientations has no common orientation with the application, and [PUUIAlbumListViewController shouldAutorotate] is returning YES
In the project general settings i have the following (which should not be changed according to apple's answer):
I can see that these functions are in fact being called but nothing helps.
Any thoughts?
Some questions i read earlier:
How to force a UIViewController to Portrait orientation in iOS 6
iOS6: supportedInterfaceOrientations not working (is invoked but the interface still rotates)
Supported orientations has no common orientation with the application, and shouldAutorotate is returning YES'
Synopsis: application(_:, supportedInterfaceOrientationsForWindow) -> Int does overwrite the General > Deployment Info. So you can ignore that .plist entirely once you provide supportedInterfaceOrientationsForWindow in the app delegate. See note about UIInterfaceOrientationMaskPortrait.
Having tried the code above every which way, in both Obj-C and Swift, the only times I get...
'UIApplicationInvalidInterfaceOrientation', reason: 'Supported orientations has no common orientation with the application, and [ViewController shouldAutorotate] is returning YES'
...is when:
using UIInterfaceOrientationPortrait instead of UIInterfaceOrientationMaskPortrait (mask is the keyword here)
or supportedInterfaceOrientations returns a mask not listed in supportedInterfaceOrientationsForWindow
A. Place this block in the the class adopting the UIApplicationDelegate protocol (typically AppDelegate.m or AppDelegate.swift):
-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
return UIInterfaceOrientationMaskAll;
else /* iphone */
return UIInterfaceOrientationMaskAllButUpsideDown;
}
supportedInterfaceOrientations will overwrite the Deployment Info and allow to dynamically differentiate iPhone from iPad at runtime.
B. Place this block in the UIViewController subclass for which you want a specific behavior (typically CustomViewController.m or CustomViewController.swift):
Obj-C
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
Swift
override func supportedInterfaceOrientations() -> Int {
let supported = UIInterfaceOrientationMask.Portrait.rawValue
return Int(supported)
}
Tested iOS 8.4
Ugh, for me it was this line in my flutter main.dart blowing me up:
await SystemChrome.setPreferredOrientations([DeviceOrientation.landscapeLeft]);

ios set specific orientation for specific views

I am making game which supports only landscape orientation but I am also using a library to share my game video but that share screen require portrait orientation , If I don't enable portrait orientation my game got crash but If I enable portrait orientation to avoid this crash then my whole game become useless by becoming portrait as it is only for landscape.
This is my game Landscape View as shown by figures below,
This is the Library Portrait View to Share video
My Game View after sharing video from library
Please help me How can I enable portrait orientation for this library to avoid crash
and my rest of the app always remain in landscape and it never goes to portrait orientation.
Thanks
Add the following method to your application's AppDelegate.m file:
// IOS 6
-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
return UIInterfaceOrientationMaskAll;
}
In both cases you must also make sure that you have added the landscape only orientation handling code to your game's main UIViewController.
// IOS 5
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
return UIInterfaceOrientationIsLandscape(toInterfaceOrientation);
}
// IOS 6
- (BOOL)shouldAutorotate {
return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight;
}
Try to implement orientation methods to your view controller.
https://developer.apple.com/library/ios/featuredarticles/ViewControllerPGforiPhoneOS/RespondingtoDeviceOrientationChanges/RespondingtoDeviceOrientationChanges.html
I hope this help you.
In the view controller you want to support orientation override supportedInterfaceOrientations method.
I did like this...
-(NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationLandscapeLeft | UIInterfaceOrientationLandscapeRight;
}

Universal app supporting portrait and Portrait upside down, but rotation not happening on iPhone - UPDATED

My app is a universal application that supports portrait and portrait upside down orientations.
My app uses a UITabBarController that has UINavigationControllers for 3 UITabBarItems.
To support of of these, i have done the following things:
1) added "supported Interface Orientations" key accordingly for both devices
2) added the following code in app delegate and all other view controllers
- (BOOL)shouldAutorotate {
return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
return (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown);
}
Everything is going as expected in iPad, but on iPhone, only some of my views (not all) do not respond to change in Orientation..!! Why is this happening??
You should check that all of your view controllers have the rotation defined, and then you should add this to them:
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return YES;
}
If you're using a navigation controller, you should create a subclass .i.e. "MyNavController" with the instructions to rotate in its implementation:
- (BOOL)shouldAutorotate {
return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
return (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown);
}
and then use it:
MyNavController *navo = [[MyNavController alloc] initWithRootViewController:myRootController];
As far as I know upside down in portrait mode for the IPhone is not allowed, cause when a user receives a phonecall, the app is on hold and he has the phone upside down. Thats why apple does not want that.

Handling iDevice rotation on iOS 6

I'm having trouble figuring out how to handle device rotation on iOS 6. I have three things that need to change separately when the device is rotated.
I have a parent UIViewController that handles multiple sub UIViewControllers or UINavigationControllers (Its basically a custom UITabBarController). I do not want this to rotate.
Each of these sub view controllers, will either rotate or not rotate depending on its own settings. (I want some to rotate and some to not).
In the tab bar, I want each tab icon (a UIView) to rotate to the orientation.
How would I go about making this happen in iOS 6, I got everything working in iOS 5.
Here is what I have so far:
In the parent UIViewController:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
return UIInterfaceOrientationPortrait;
}
- (BOOL)shouldAutorotate
{
return NO;
}
- (BOOL)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
In the sub view controllers:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
return YES;
}
- (BOOL)shouldAutorotate
{
return YES;
}
- (BOOL)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskAll;
}
There's a bit more to this to support iOS6 correctly. The iOS 6 Release Notes sketch things out:
https://developer.apple.com/library/ios/#releasenotes/General/RN-iOSSDK-6_0/_index.html
This bit might be useful:
For compatibility, view controllers that still implement the shouldAutorotateToInterfaceOrientation: method do not get the new autorotation behaviors. (In other words, they do not fall back to using the app, app delegate, or Info.plist file to determine the supported orientations.) Instead, the shouldAutorotateToInterfaceOrientation: method is used to synthesize the information that would be returned by the supportedInterfaceOrientations method.
But you should also take a look at Session 236 from WWDC 2012 - The Evolution of View Controllers.
If you want to support different orientation in navigation stack, you must subclass UINavigationController first and override supportedInterfaceOrientations.
- (NSUInteger)supportedInterfaceOrientations
{
//I want to support portrait in ABCView at iPhone only.
//and support all orientation in other views and iPad.
if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone)
{
// find specific view which you want to control.
if ([[self.viewControllers lastObject] isKindOfClass:[ABCView class]])
{
return UIInterfaceOrientationMaskPortrait;
}
}
//support all
return UIInterfaceOrientationMaskAll;
}

Resources