Shouldautorotate returning wrong value - iphone

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;

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

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);

how to know the device orientation correctly

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.

Hide UIView on device rotation - doesn't work when device is horizontal

I'm trying to hide an image in a view controller when the device is rotated. I'm posting a notification in PlayerViewController and am listening for it in the app delegate, which is responsible for the bannerView:
- (void)orientationChanged:(NSNotification *)notification {
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
if ((orientation == UIDeviceOrientationLandscapeLeft) ||
(orientation == UIDeviceOrientationLandscapeRight)) {
bannerView.hidden = ([[self.navigationController visibleViewController] isKindOfClass:[PlayerViewController class]]) ? YES : NO;
} else {
bannerView.hidden = NO;
}
}
The PlayerViewController sends a notification and the app delegate hides the bannerView. However, when the device is laid flat on a table, the image shows. Works fine when the device is held vertically but horizontally the image appears... odd.
Here is the code to send the notification:
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
duration:(NSTimeInterval)duration {
if (UIInterfaceOrientationIsLandscape(toInterfaceOrientation)) {
... hide other stuff in this view controller
}
Any ideas why this odd behavior is occurring?
Just one tidbit more information. In the simulator the image shows when the device is in upside-down orientation, even though I have:
- (BOOL)shouldAutorotateToInterfaceOrientation (UIInterfaceOrientation)interfaceOrientation
{
if (interfaceOrientation == UIInterfaceOrientationLandscapeRight || interfaceOrientation == UIInterfaceOrientationLandscapeLeft || interfaceOrientation == UIDeviceOrientationPortrait) {
return YES;
} else {
return NO;
}
}
Your error might be happening because of when you're posting the notification.
willAnimateRotationToInterfaceOrientation is called before the orientation change takes place (hence the "will" in the method name). So if we're going from portrait to landscape, the current orientation may still be reported as portrait (it may not, it depends).
Now, the willAnimate... call returns the toInterfaceOrientation - the orientation that is going to happen.
You trigger your notification when you receive the willAnimate... call, and inside that notification call [[UIDevice currentDevice]orientation]: which will return portrait. Instead of requesting the orientation in your notification method you should instead pass the orientation provided in the willAnimate call.
If that wasn't clear, the one sentence summary: willAnimateRotationToInterfaceOrientation is called before the rotation changes.

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