I have the following code for my universal app but I'm getting this weird log when I run the app. Everything seems to be working fine, however.
- (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if (NSClassFromString(#"UISplitViewController") != nil && UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
return YES;
}
else
return NO;
}
In the console:
The view controller <UINavigationController: 0x1468d0> returned NO from -shouldAutorotateToInterfaceOrientation: for all interface orientations. It should support at least one orientation.
The message says everything:
It should support at least one orientation.
In your else statement, NO is returned independently of the orientation. If NO here means "portrait only", do the check and return YES for portrait:
else
return
(interfaceOrientation == UIInterfaceOrientationPortrait) ?
YES :
NO ;
Or the more succinct (but less fancier) version:
else
return (interfaceOrientation == UIInterfaceOrientationPortrait);
I think that means that your if condition is always false. There should always be a case where you return YES for either portrait or landscape regardless of whether it's an iPad or you have UISplitViewController class. Yours will always return NO for an iPhone for instance. Start with something more like this and then perhaps allow landscape only if blahblah:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if (NSClassFromString(#"UISplitViewController") != nil && UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
return YES;
}
else
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait) || (interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown);
}
I think that your if condition always fails, so you're probably always returning NO which means "I don't support any orientation" which is obviously not true... what is the lowest target you want to support?
If your else is supposed to handle iPhone/iPod, you should return YES for at least one orientation:
return (interfaceOrientation == UIInterfaceOrientationPortrait);
Or
return inOrientation == UIDeviceOrientationLandscapeLeft
|| inOrientation == UIDeviceOrientationLandscapeRight
|| inOrientation == UIDeviceOrientationPortrait
|| inOrientation == UIDeviceOrientationPortraitUpsideDown;
if you plan to support all orientations.
If you care about supporting iOS versions lower than 3.2 and want to test it on Simulator, you may want change your "iPad check", to sth like this.
- (BOOL)amIAnIPad {
// This "trick" allows compiling for iOS < 3.2 and testing on pre 3.2 simulators
#if (__IPHONE_OS_VERSION_MAX_ALLOWED >= 30200)
if ([[UIDevice currentDevice] respondsToSelector: #selector(userInterfaceIdiom)])
return ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad);
#endif
return NO;
}
More on that trick, can be found on Jeff LaMarche's blog.
Related
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
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);
I am working on window based iPhone app.
I wanted to add rotation feature by using,
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
but it does not work.
What is wrong with this.
Note: xCode 4 , iOS 4.3
Regards.
In Xcode 4 click on the project the very top item in the left bar and then click on the summary tab and make sure the supported orientations is set correctly.
If that is fine then you might try rewriting the return line to be something like this:
return(interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationLandscapeLeft || interfaceOrientation == UIInterfaceOrientationLandscapeRight);
If that doesn't work just try return YES; and see if the views will rotate.
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
I am working on a universal app that should be able to run on iPad and iPhone. The Apple iPad docs say to use UI_USER_INTERFACE_IDIOM() to check if I am running on iPad or iPhone, but our iPhone is 3.1.2 and will not have UI_USER_INTERFACE_IDIOM() defined. As such, this code breaks:
//iPhone should not be flipped upside down. iPad can have any
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
return YES; //are we on an iPad?
} else {
return interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown;
}
}
In Apple's SDK Compatibility Guide they suggest doing the following to check if the function exists:
//iPhone should not be flipped upside down. iPad can have any
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
if(UI_USER_INTERFACE_IDIOM() != NULL &&
UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
return YES; //are we on an iPad?
} else {
return interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown;
}
}
This works, but results in the compiler warning: "Comparison between pointer and integer." After digging around I figured out that I can make the compiler warning disappear with the following cast to (void *):
//iPhone should not be flipped upside down. iPad can have any
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
if((void *)UI_USER_INTERFACE_IDIOM() != NULL &&
UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
return YES; //are we on an iPad?
} else {
return interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown;
}
}
My question is this: Is the last code block here okay/acceptable/standard practice? I couldn't find anyone else doing something like this with quick searching which makes me wonder if I missed a gotcha or something similar.
Thanks.
You need to build apps for iPad against the 3.2 SDK. As such it will build correctly, and the UI_USER_INTERFACE_IDIOM() macro will still work. If you want to know how/why, look it up in the docs - it is a #define, which will be understood by the compiler and compile into code that will run correctly on 3.1 (etc).