shouldAutorotateToInterfaceOrientation not working - iphone

- (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
return YES;
}
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
}
are not working, and i dont hv any idea,why.
When i try debugging, and rotate the device, these method not called.
I just want to detect the orientation
if orientation = landscape
perform action a
else
perform action b
Many Thanks

I agree with Clafou, how you setup your app can mess with rotation.
Add this and see if it fires:
-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
BOOL isPortraitOrientation;
if ((self.interfaceOrientation == UIDeviceOrientationPortrait) || (self.interfaceOrientation == UIDeviceOrientationPortraitUpsideDown)){
isPortraitOrientation = YES;
} else if((self.interfaceOrientation == UIDeviceOrientationLandscapeLeft) || (self.interfaceOrientation == UIDeviceOrientationLandscapeRight)){
isPortraitOrientation = NO;
}
}

Related

iOS6 Device Rotation To Be Restricted

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

Getting wrong orientation

I am having an issue in my application which drives me mad. In my application, I rotate the simulator to the landscape mode, but in my below function, I get portrait orientation.
What is the problem here? Please help me out.
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if ( interfaceOrientation == UIInterfaceOrientationPortrait ||
interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown )
{
NSLog(#" portrait orientation");
}
else
{
NSLog(#"Landscape");
}
return YES;
}
First set the orientation value is the method
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Overriden to allow any orientation.
NSLog(#"shouldAutorotateToInterfaceOrientation called...");
if (interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIDeviceOrientationPortraitUpsideDown)
defaultOrientation = 0;
else if(interfaceOrientation == UIInterfaceOrientationLandscapeLeft || interfaceOrientation == UIInterfaceOrientationLandscapeRight)
defaultOrientation = 1;
[self setTheOrientation];
return YES;
}
Now set the values of the coordinates which you require according to the boolean values in the setTheOrientation method.
The method returns BOOL, you have to return either YES or NO
Why you did't return a BOOL value? YES or NO to tell the OS that you're gonna handle corresponding orientation events.
If you want portrait mode then add return TRUE in if clouse and If you want landscape then add return TRUE in else clouse and if you want both mode then just type return TRUE in shouldAutoRotate clouse

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;

My app crashes after multiple rotates

My app is crashing when I try and rotate it more than a couple of times. I first thought it was just the iPhone Simulator, so I loaded the app onto an iPod touch, and it crashed after fewer rotates in a row. I suspect it's a memory leak in one of my rotate methods. The only place I can think that the crash is being caused is in willRotateToInterfaceOrientation:duration:. The only two methods related to rotate that I've added/extended are shouldAutorotateToInterfaceOrientation: and willRotateToInterfaceOrientation:duration and I don't think it's the first because it only contains the two words: return YES;. Here is my willRotateToInterfaceOrientation:duration: method so you can review it and see where the possible memory leak is.
-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)orientation duration:(NSTimeInterval)duration
{
UIFont *theFont;
if ((orientation == UIInterfaceOrientationLandscapeLeft) || (orientation == UIInterfaceOrientationLandscapeRight))
{
theFont = [yearByYear.font fontWithSize:16.0];
yearByYear.font = theFont;
[theview setContentSize:CGSizeMake(460.0f, 635.0f)];
}
else
{
theFont = [yearByYear.font fontWithSize:10.0];
yearByYear.font = theFont;
[theview setContentSize:CGSizeMake(300.0f, 460.0f)];
}
[theFont release];
}
yearByYear is a UITextView and theview is a UIScrollView.
You shouldn't be releasing theFont. You don't own the object.
You can also simplify what you're doing to:
-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)orientation duration:(NSTimeInterval)duration {
if ((orientation == UIInterfaceOrientationLandscapeLeft) || (orientation == UIInterfaceOrientationLandscapeRight)) {
yearByYear.font = [yearByYear.font fontWithSize:16.0]
[theview setContentSize:CGSizeMake(460.0f, 635.0f)];
}
else
{
yearByYear.font = [yearByYear.font fontWithSize:10.0]
[theview setContentSize:CGSizeMake(300.0f, 460.0f)];
}
}
Getting rid of theFont completely.

UIDevice Orientation

I have the following code in a method. When I run this in the simulator the debugger skips right over the code?? What am I missing?
if (([[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeLeft) ||
([[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeRight))
{
} else {
}
The best way to determine interface orientation is to look at status bar orientation:
UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
if(orientation == UIInterfaceOrientationPortrait ||
orientation == UIInterfaceOrientationPortraitUpsideDown) {
//Portrait orientation
}
if(orientation == UIInterfaceOrientationLandscapeRight ||
orientation == UIInterfaceOrientationLandscapeLeft) {
//Landscape orientation
}
UIDevice class measures orientation based on accelerometer and if device lays flat, it won't return the correct orientation.
Note that there's a macro UIDeviceOrientationIsLandscape and UIDeviceOrientationIsPortrait, so instead of comparing it separately to LandscapeLeft and LandscapeRight you could just do it like this:
if (UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation))
{
}
Update 2
This shouldn't matter, but try turning on orientation notifications:
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(detectOrientation) name:#"UIDeviceOrientationDidChangeNotification" object:nil];
Update
My bad, I assumed it was empty.
Try removing the or statement and just test for a single orientation. See if that fixes it. Maybe there is a bracket problem or something silly.
I have the following test working in production code, so your technique should work:
if (([[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeLeft) ||
([[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeRight)) {
}
Original Answer
You have to actually put statements in the if blocks to get it to step in.
The debugger is smart enough to skip over empty blocks.
Another way of doing this without turning on orientation notification would be to
Step 1: Save the current orientation in a local variable myCurrentOrientation and assign it like this:
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
duration:(NSTimeInterval)duration
{
myCurrentOrientation = toInterfaceOrientation;
}
Step 2: Use myCurrentOrientation for your check
if (UIInterfaceOrientationIsLandscape(myCurrentOrientation) == YES) {
// landscape
}
else {
// portrait.
}
Say you are inside a Springboard tweak and want to show something depending on the orientation of the current app, then you can use this (jailbreak only):
UIInterfaceOrientation o = [[UIApplication sharedApplication] _frontMostAppOrientation];
Heh you need to call [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]
before obtaining the value. Have a look at documentation of this method. Took me a while to track this down.
I recommend you to use my highlighted code instead of yours to safe some code of lines.
-(void) viewDidLoad
{
[super viewDidLoad];
[self rotations];
}
-(void)rotations
{
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(orientationChanged:)
name:UIDeviceOrientationDidChangeNotification
object:nil];
}
-(void) orientationChanged:(NSNotification *)notification
{
//USE THIS PART
//USE THIS PART
//USE THIS PART
//USE THIS PART
//USE THIS PART
if (UIDeviceOrientationIsPortrait([UIDevice currentDevice].orientation))
{
}
}
INSTEAD OF
if([[UIDevice currentDevice] orientation] == UIInterfaceOrientationPortrait ||
[[UIDevice currentDevice] orientation] == UIInterfaceOrientationPortraitUpsideDown)
{
}
Here is a method to find the orientation and the true center of the screen. I used Tuszy's method so I could set UIActivityIndicatorView properly.
- (BOOL) isPortraitOrientation {
UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
if(orientation == UIInterfaceOrientationPortrait ||
orientation == UIInterfaceOrientationPortraitUpsideDown) {
return true;
}
if(orientation == UIInterfaceOrientationLandscapeRight ||
orientation == UIInterfaceOrientationLandscapeLeft) {
return false;
}
return false;
}
And the way to get center...
- (void) findMyUIViewCenter {
CGPoint myCenter;
if ([self isPortraitOrientation]) {
myCenter = self.view.center;
}
else {
myCenter = CGPointMake(self.view.frame.size.height / 2.0, self.view.frame.size.width / 2.0);
}
NSLog(#"true center -- x:%f y:%f )",myCenter.x,myCenter.y);
}