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
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 want to know the device orientation when user start my app , in order to produce different view. What I find strange is as below:
- (void)viewDidLoad
{
if ([UIDevice currentDevice].orientation == UIDeviceOrientationPortrait) {
NSLog(#"1");
}
if ([UIDevice currentDevice].orientation == UIDeviceOrientationLandscapeRight) {
NSLog(#"2");
}
if ([UIDevice currentDevice].orientation == UIDeviceOrientationLandscapeLeft) {
NSLog(#"3");
}
if ([UIDevice currentDevice].orientation == UIDeviceOrientationPortraitUpsideDown) {
NSLog(#"4");
}
}
No one is printed! I did it on the ipad simulator and I think the orientation should be UIDeviceOrientationPortrait. Why this happen? and how to know the orientation correctly?
Try to use
[UIApplication sharedApplication].statusBarOrientation
instead of
[UIDevice currentDevice].orientation
It may be the case that the simulator simply cannot be in an orientation state (it makes no sense, as you can't really rotate your computer...) Have you checked whether it returns UIDeviceOrientationUnknown?
The documentation or UIDevice states:
You get the current orientation using the orientation property or
receive change notifications by registering for the
UIDeviceOrientationDidChangeNotification notification. Before using
either of these techniques to get orientation data, you must enable
data delivery using the beginGeneratingDeviceOrientationNotifications
method
http://developer.apple.com/library/ios/#documentation/uikit/reference/UIDevice_Class/Reference/UIDevice.html
So it is probably that you get Unkown orientation because you never started the orientation notifications generation.
You should also log the value in your viewDidLoad to confirm exactly what you receive when you get the orientation. That would be a good starting point for further investigation.
Use this :-
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
if(interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)
{
//code for portrait
}
else
{ //code for Landscape
}
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight || interfaceOrientation == UIInterfaceOrientationPortrait ||interfaceOrientation == UIInterfaceOrientationLandscapeLeft ||interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown);
}
(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation is the delegate method oa uiviewcontroller.
According to the docs, the orientation property of UIDevice will always return 0 (i.e., UIDeviceOrientationUnknown) unless -beginGeneratingDeviceOrientationNotifications has been called first. This method will enable the accelerometer, deliver notification changes, and update the orientation property of the UIDevice singleton.
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.
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
}
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;