I have a custom camera overlay that, like all camera views, is default in landscape mode. I have some orientation change logic that detect when the orientation changes so I can rotate the buttons and views that I have placed. Also, I have edited the shouldAutoRotateInterfaceTo method so it does not rotate while the camera is on:
- (BOOL)shouldAutorotateToInterfaceOrientation
(UIInterfaceOrientation)interfaceOrientation {
if (cameraIsOn) {
return NO;
}
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
Problem: the camera view still rotates into Portrait mode when I tilt the camera into Landscape. This results in the device being in Landscape position while the view is in Portrait, running off of the screen.
If it helps, here is the method I use to detect orientation changes and transform my buttons:
- (void)cameraOrientationChanged {
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
CGAffineTransform transform;
switch (orientation) {
case UIDeviceOrientationPortrait:
transform = CGAffineTransformIdentity;
self.rotatePrompt.hidden = NO;
break;
case UIDeviceOrientationPortraitUpsideDown:
//transform = CGAffineTransformMakeRotation(180*M_PI/180);
transform = CGAffineTransformIdentity;
self.rotatePrompt.hidden = NO;
break;
case UIDeviceOrientationLandscapeLeft:
//transform = CGAffineTransformMakeRotation(90*M_PI/180);
self.rotatePrompt.hidden = YES;
transform = CGAffineTransformIdentity;
break;
case UIDeviceOrientationLandscapeRight:
//transform = CGAffineTransformMakeRotation(-90.0*M_PI/180);
transform = CGAffineTransformMakeRotation(180*M_PI/180);
self.rotatePrompt.hidden = YES;
break;
default:
transform = CGAffineTransformIdentity;
break;
}
self.shootButton.transform = transform;
self.cameraTypeButton.transform = transform;
self.photoLibraryButton.transform = transform;
self.changeCameraDirectionButton.transform = transform;
self.flashButton.transform = transform;
self.videoTimerLabel.transform = transform;
self.closeCameraButton.transform = transform;
}
Note This seemed to be working ok before I upgraded to iOS 5.
More Info By looking at my Xib file, I can see that I created the overlay in Portrait mode. When the camera overlay rotates it is moving into Portrait mode while the device is being help in Landscape position.
Even more peculiar, whenever this happens (it does not always happen), I noticed that shouldAutorotateToInderfaceOrientation is not being called in the view controller. I bet that has something to do with the problem here.
The problem is with my navigation controller setup. UIImagePickerController sends the rotation message to the root view controller's shouldAutoRotateToInterface: method. However, since I copied the class from an older project (iOS 3), it did not have the shouldAutoRotateToInterface: method automatically copied. Now that I wrote the method in my root view controller, to rotation problem is fixed.
You seem to be using
UIDeviceOrientation
when you really should be usingUIInterfaceOrientation
.UIDeviceOrientation
has many more states thanUIInterfaceOrientation
, so this could result in a device state being something other than what you were expecting for an interface state, for instanceUIDeviceOrientationFaceUp
can be returned even when the interface orientation (to the user) looks like it should beUIInterfaceOrienataionLandscape
. So in your case, yourdefault
switch case may be returning more often than you would expect for it to.If it were me, I would change your
- (void)cameraOrientationChanged
method to- (void)cameraOrientationChangedTo:(UIInterfaceOrientation)orientation
and call that method inshouldAutorotateToInterfaceOrientation
:UIDeviceOrientation
vsUIInterfaceOrientation
: