Forcing the portrait orientation for my View - objective-c

I am working on ARC based project. My project is targeted iOS 4.3 I want to force the
Portrait orientation to one of my view. The following doesn't seem to work for me.
[[UIDevice currentDevice] performSelector:NSSelectorFromString(#"setOrientation:") withObject:(id)UIInterfaceOrientationPortrait];
Any help on this?

First of all the viewController to which orientations need to supported must implement the below method passing the supported orientations.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
Later to manually rotate the view set the device orientation directly using
[[UIDevice currentDevice] setOrientation:UIInterfaceOrientationPortrait];
if this doesn't work use
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:YES];
remember if you return NO for the setting orientation in shouldAutoRotate this may not work. Also check this in both ios5 & ios6, i have tried in ios5.
EDIT: For iOS5 or iOS6 where setOrientation doesn't exist
[[UIDevice currentDevice] performSelector:NSSelectorFromString(#"setOrientation:") withObject:(id)UIInterfaceOrientationPortrait];
this works fine, but this may be a private api now.

Related

Best way to Supporting Multiple Interface Orientations - iOS8

I have been trying to convert few old apps written in objC long ago in iOS4 which support multiple ViewController with different orientation.
(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
Above Method is called in app delegate from ViewController and Desire Orientation was set but seems stopped working with iOS8.
I have tried number of solution like creating Category of UINavigation controller etc, but nothing seems working with iOS8.
What is best approach to handle Multiple Orientation for both iPhone and iPad.
Furthermore, I am not using Storyboard with size classes, in plist i am only supporting portrait orientation.
Check all the orientation you want to support in device.
For that go to Project target-> Deployment info -> Device orientation-> Tick mark the desired orientation.
From iOS 6 onwards, you've to use.
- (BOOL)shouldAutorotate {
UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
if (orientation == UIInterfaceOrientationPortrait) {
// your code for portrait mode
}
return YES;
}
Refer to shouldAutorotateToInterfaceOrientation not being called in iOS 6

Launching an app in landscape under ios6 while supporting all orientations

I have done a ton of research and am still unable to find a solution for this...
I have an app that supports all orientations. When the app is run on the iPad I want it to launch in landscape mode. The user can then rotate to portrait if they choose. Under ios5, I accomplished this by setting supported orientations for the iPad in the info.plist file to lansdcape left. I then used the shouldAutorotateToInterfaceOrientation method in each view controller to allow all orientations when the app was running.
I then changed my code to support the new orientation methods for iOS6 but when I ran the app on the iPad, it was not rotating at all. I then changed the info.plist file to support all orientations for the iPad. This solved the problem with the iPad not autorotating but now I can't figure out how to force the app to initially open in landscape mode. Any ideas?
Thanks in advance for any help you can give!
I ran into something similar recently, although my problem was that I wanted to force portrait in an iPhone app, but allow movies to play in landscape. Here's what I did:
Add a property to my app delegate to store the orientations I want to allow:
#property (nonatomic, assign) NSUInteger supportedOrientations;
Then in the app delegate, implemented the new iOS 6 method:
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
return supportedOrientations;
}
On app launch I forced portrait:
self.supportedOrientations = UIInterfaceOrientationMaskPortrait;
And then once the app had finished launching and I'd shown my root view controller, I set it to support both orientations:
self.supportedOrientations = UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscape;
I had to add the additional step of subclassing my UINavigationController to prevent rotation after that, because I wanted to allow landscape video but not rotation:
- (BOOL)shouldAutorotate {
return FALSE;
}
But that's just for info. You won't need that

setStatusBarOrientation:animated: not working in iOS 6

I've used this code to force an orientation change back to portrait when the user is finished watching the video (it allows viewing in landscape mode), before popping the video view controller off the navigation controller:
//set statusbar to the desired rotation position
[[UIApplication sharedApplication] setStatusBarOrientation:UIDeviceOrientationPortrait animated:NO];
//present/dismiss viewcontroller in order to activate rotating.
UIViewController *mVC = [[[UIViewController alloc] init] autorelease];
[self presentModalViewController:mVC animated:NO];
[self dismissModalViewControllerAnimated:NO];
[[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationNone];
This worked perfectly until iOS 5.1.1. I've even tried to use the new present/dismiss methods after reading in another post that those should be used now:
[self presentViewController:mVC animated:NO completion:NULL];
[self dismissViewControllerAnimated:NO completion:NULL];
The problem is it doesn't work at all. After I rotated the video viewer to landscape and then pop it, my settings view (table view controller) comes back, but also in landscape mode.
I've even tried the tip from Here
"The setStatusBarOrientation:animated: method is not deprecated outright. However it now works only if the supportedInterfaceOrientations method of the topmost full screen view controller returns 0. This puts the responsibility of ensuring that the status bar orientation is consistent into the hands of the caller."
So I've experimented with setting a flag to force supportedInterfaceOrientations to return 0 (before calling the first code block above) but it doesn't work either.
Does anybody have a solution for this?
Thanks for your time and effort.
setStatusBarOrientation method has changed behaviour a bit. According to Apple documentation:
The setStatusBarOrientation:animated: method is not deprecated
outright. It now works only if the supportedInterfaceOrientations
method of the top-most full-screen view controller returns 0
Your root view controller should answer false to the method shouldAutorotate in order that your app responds to setStatusBarOrientation:animated
From Apple Documentation: "if your application has rotatable window content, however, you should not arbitrarily set status-bar orientation using this method"
To understand that, put a breakpoint in the shouldAutorotate method and you will see that it is called juste after setting the status bar orientation.
Here is how I fixed.
https://stackoverflow.com/a/14530123/1901733
The current question is linked with the question from the url above.
The statusBarOrientation is a real problem in ios6.

Force iOS app to launch in landscape mode

I am developing an app for iOS 5, which have to run in landscape mode. My problem is that I cannot get it to flip initially.
I have tried the adding "Initial interface orientation" set to "Landscape (right home button)"
and adding the following method to my view controller:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}
I can wrap my head around how it is supposed to work. (I found the code here)
I am also wondering how to use the "Supported Device Orientation" available in the Xcode 4.2 project setup, it does not seem to do anything.
I have been looking around the website and have not been able to find an example that solves my problem.
Thank you.
In your application’s Info.plist file, add the UIInterfaceOrientation
key and set its value to the
landscape mode. For landscape
orientations, you can set the value
of this key to
UIInterfaceOrientationLandscapeLeft
or
UIInterfaceOrientationLandscapeRight.
Lay out your views in landscape mode and make sure that their autoresizing options are set correctly.
Override your view controller’s shouldAutorotateToInterfaceOrientation: method and return YES only for the
desired landscape orientation and NO
for portrait orientations.
use the following in appDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight];
also set the required orientations in
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}
//Here are some iOS6 apis, used to handle orientations.
- (BOOL)shouldAutorotate NS_AVAILABLE_IOS(6_0)
- (NSUInteger)supportedInterfaceOrientations - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
When you click on your project's name in XCode and select your target under TARGETS, under Summary tab there's a visual representation of the supported device orientation settings. That was how I managed to do it.
i think if you at the supported interface orientations in the project plist it will work. just add a new line called "Supported interface orientations" and make it of array type and add 2 items for each of teh landsape views u want. havent tested this just a quick guess
Try this this will help you, write this code in you viewdidload.
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight];

Interface Orientation won't change to Landscape on App Launch

i stuck on a problem that drives me crazy!
I have an iPad application starting with a TabBarViewController. Every Tab has it's own ViewController and nib-file.
To make interface orientation possible I added all orientations to my info.plist and subclassing my TabBarController to set:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
Every View is autoresized and formatted well for displaying the right Orientation if I rotate the Interface. If I test it in the simulator, everything looks fine and I can rotate between the Orientations.
Now the point that drives me crazy:
If I launch the App in Portrait Mode, all works fine.. but if I launch in Landscape, I get an error and my Interface orientation seems still to be Portrait, while the Simulator is in Landscape Mode!!
The Error:
2011-05-24 21:50:15.011 Project[57995:207] Using two-stage rotation animation. To use the smoother single-stage animation, this application must remove two-stage method implementations.
I checked for Orientation like this:
-(void)viewWillAppear:(BOOL)animated{
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
if ((orientation == UIInterfaceOrientationLandscapeLeft) || (orientation == UIInterfaceOrientationLandscapeRight)) {
NSLog(#"Orientation: Landscape");
}
else{
NSLog(#"Orientation: Portrait");
}
}
The Log says it is in "Landscape" Mode if I launch in Landscape, but if I change tab to another it looks terrible because the View is displayed in Portrait mode instead.
On change back to the start-view where i asked for Orientation… the log displays "Portrait"… but the Simulator is still Landscape!
I can't figure out why the Orientation is Portrait on start,…
even if I start in Landscape…
Any idea how to solve this problem?
Ok. So the documentation says viewWillAppear: is called prior to all animations. And when your app starts, its initial orientation is Portrait. Based on what your orientation is, it then rotates to that orientation. Since it animates to the orientation off screen, this must be called after viewWillAppear:/ So when viewWillAppear: is called, its still in Portrait. I tested this myself.
I solved the problem!
Simply used this in viewWillAppear method of all my Views, to make it work when started in Landscape mode:
if(([[UIApplication sharedApplication]statusBarOrientation] == UIInterfaceOrientationLandscapeLeft) || ([[UIApplication sharedApplication]statusBarOrientation] == UIInterfaceOrientationLandscapeRight)){
//Landscape View
}
else{
//Portrait View
}
Works fine for me!