iOS6 Device Rotation To Be Restricted - iphone

For my app, I want to let the device rotate anyway but upside-down. This is working fine. However, I want to stop the app from rotating specifically from
landscape left -> landscape right - and vice versa
If anyone is curious, this is because that rotation messes up my layouts, as they each rotate from a common point
My code for iOS 5, which I think would work, is like this:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
NSLog(#"Rotating");
if((lastOrient == 3 && toInterfaceOrientation == 4) || (lastOrient == 4 && toInterfaceOrientation == 3)){
lastOrient = toInterfaceOrientation;
return NO;
}
lastOrient = toInterfaceOrientation;
return YES;
}
Where 3= landscape left and 4= landscape right
Any suggestions on how to do this with iOS6? Or a completely different solution?

shouldAutorotateToInterfaceOrientation is deprecated in ios6. Use this:
- (BOOL)shouldAutorotate {
UIInterfaceOrientation orientation = [[UIDevice currentDevice] orientation];
if (lastOrientation==UIInterfaceOrientationPortrait && orientation == UIInterfaceOrientationPortrait) {
return NO;
}
return YES;
}
Haven't tested this code. You can get more info on these posts:
shouldAutorotateToInterfaceOrientation is not working in iOS 6
shouldAutorotateToInterfaceOrientation not being called in iOS 6

Ok I answered my own question here:
The good news is, there is definitely a way to do this! So heres the basics:
In iOS6, it is up to the appDelegate to handle whether the app can rotate in general. Then, when the device gets a rotation signal, it will ask your view for its supported orientations. This is where I implemented my code. In fact, shouldAutorotate() plays no role in the solution.
So I create a variable to keep track of the last orientation, and change it in
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{
This way I can compare orientations
-(NSUInteger)supportedInterfaceOrientations
{
NSLog(#"Last Orient = %d", lastOrient);
NSUInteger orientations = UIInterfaceOrientationMaskPortrait;
if (lastOrient != 3 && lastOrient != 4) {
NSLog(#"All good, rotate anywhere");
return UIInterfaceOrientationMaskAllButUpsideDown;
}
else if(lastOrient == 3){
orientations |= UIInterfaceOrientationMaskLandscapeRight;
NSLog(#"Can only rotate right");
}
else if(lastOrient == 4){
orientations |= UIInterfaceOrientationMaskLandscapeLeft;
NSLog(#"Can only rotate left");
}
return orientations;
}
Seems to work for me. Slightly a hack, but it does what it needs to do

Related

Disable Landscape Orientation in IOS5

I want to eliminate Landscape Orientation in my application, which is built for IOS 5. In IOS 6 I know this is possible - but it doesn't seem to be working for me in the earlier version.
I am setting only two orientations in my plist file (Portrait w/Home Button on Top and Portrait w/Home Button on Bottom). Regardless, Landscape still crops up in IOS 5.
Is there something further I need to do to eliminate this from happening?
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
// return (interfaceOrientation == UIInterfaceOrientationPortrait);
if(interfaceOrientation == UIInterfaceOrientationLandscapeLeft ||interfaceOrientation == UIInterfaceOrientationLandscapeRight)
{
return NO;
}
else
{
return YES;
}
}
write this code in .m file for ios5 orientation
let me know it is working or not....
Happy Coding!!!!
This will work. Go to storyboard deselect the orientation you don't want and in view controller, write this code:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation==UIInterfaceOrientationPortraitUpsideDown || interfaceOrientation==UIInterfaceOrientationPortrait );
}

having issue with shouldAutorotateToInterfaceOrientation

I have the following code in my UIViewController and I am testing for iOS 5 in a device and both simultor.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if (IS_IPHONE){
return interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown;
} else {
return YES;
}
}
I put a breakpoint and it is indeed getting called, however it still rotates to landscape. Why is this?
Because you told it to do so. return interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown; means that you want to autorotate to every direction except portrait upside-down, and that includes landscape. For iPad, even this constraint is missing, so it will autrotate to any orientation.
(You should have a fresh breath of documentation...)
Use this instead
return (interfaceOrientation == UIInterfaceOrientationPortrait);

convert iphone to ipad but screen do not auto rotate while rotate the ipad

I convert my tabbar based iphone app to ipad version with different ~ipad.xib, the only different is the ui element size. Now my question is that it can't auto rotate the screen in ipad version, i.e. I upsidedown the ipad, but the ui don't rotate upsidedown.
You need to return YES for the shouldAutorotateToInterfaceOrientation: for all view controllers featured in your tab bar, for iPad only (UI_INTERFACE_IDIOM()...). The default code from your iPhone controllers probably only returns YES if it is portrait, if that is all you selected when initially creating the project.
Here is the code I use for this situation (iPhone, portrait only, iPad, all orientations):
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
return YES;
else
return toInterfaceOrientation == UIInterfaceOrientationPortrait;
}
Tab bar controller can not auto rotate. you have to rotate all the component.
You can use this code to accomplish your task in case of universal apps
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
BOOL ret;
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad){
// iPad-specific code
if (interfaceOrientation != UIInterfaceOrientationPortrait) {
ret = YES;
}else{
ret = NO;
}
} else {
// iPhone-specific code
ret = YES;
}
return ret;
}
You need to modify 'Supported Device Orientations' to include your new orientations

UIInterfaceOrientation bug?

In my iPhone app I need to detect the current orientation and I have to determine if I'm in portrait or landscape. I use this code:
UIInterfaceOrientation orientation = [[UIDevice currentDevice] orientation];
if (orientation == UIInterfaceOrientationPortrait || orientation == UIInterfaceOrientationPortraitUpsideDown) {
NSLog(#"portrait");
...
} else {
NSLog(#"landscape");
...
}
Everything is ok when my iPhone is in my hand.
But when i put it on the table and i run the application, the content is displayed on the screen in portrait mode and my code goes to else and NSLog prints landscape.
Is my test incomplete ? How to prevent this case ?
EDIT : the test is performed in my controller viewDidLoad method and my application handle rotation.
UIDevice.orientation is of type UIDeviceOrientation, which is a superset of UIInterfaceOrientation. You are probably getting the value UIDeviceOrientationFaceUp.
This underscores that yes, your test is incomplete. You should write something like this:
UIInterfaceOrientation orientation = [[UIDevice currentDevice] orientation];
if (orientation == UIInterfaceOrientationPortrait || orientation == UIInterfaceOrientationPortraitUpsideDown) {
NSLog(#"portrait");
...
} else if (orientation == UIInterfaceOrientationLandscapeLeft || orientation == UIInterfaceOrientationLandscapeRight) {
NSLog(#"landscape");
...
} else {
NSLog(#"WTF? %d", orientation);
assert(false);
}
Then, you'll know if you if you've missed something.
UIDevice.orientation can return that the device is flat or upside down (not inverted portrait, upside-down as in laying on its face). Instead call UIViewController.interfaceOrientation on your root view controller.
I would recommend using UIDeviceOrientationIsValidInterfaceOrientation(orientation)
It will tell you if its a valid orientation (valid being either landscape or portrait, not FaceUp/FaceDown/UnKnown). Then you can treat it as if its portrait if its unknown.
This is how I do it:
if (UIDeviceOrientationIsValidInterfaceOrientation(interfaceOrientation) && UIInterfaceOrientationIsLandscape(interfaceOrientation)) {
// handle landscape
} else {
// handle portrait
}

Shouldautorotate returning wrong value

I just tried adding some print statements to my shouldautorotate method and noticed that it checks it 4 times which does make sense but even though I am not switching mode from portrait to landscape,
it returns portrait 3 times and on the fourth time, it returns landscape even though my simulator is not in landscape.
if(interfaceOrientation == UIInterfaceOrientationLandscapeLeft){
NSLog(#"landscape left");
}else if (interfaceOrientation == UIInterfaceOrientationLandscapeRight) {
NSLog(#"landscape right");
}else if(interfaceOrientation == UIInterfaceOrientationPortrait){
NSLog(#" portrait");
}else if(interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown){
NSLog(#"portrait upsidedown");
}
Any one knows why?
Try putting that code into the didAutorotate or the willAutorotate method. shouldAutorotate is only supposed to return YES or NO.
I'm theorising that shouldAutorotate is checked regularly, whereas didAutorotate is only fired of when it detects an orientation shift.
This is the code I use to check:
- (void) reOrient{
if(UIInterfaceOrientationIsPortrait(self.interfaceOrientation)){
} else {
}
}
That is in a method I created called reOrient which is called from my didAutorotate
- (void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation{
[self reOrient];
}
Just make sure when you create a new method like reOrient that you declare it in the header as well (I kept forgetting when I was starting out) as below:
- (void)reOrient;