I am trying to write an app with some camera function, and I use an overlay view to decorate it with an image.
This is how I implement the app:
I use the UIImagePickerController to who the user what the camera takes in, and add a UIImageView onto the cameraOverlayView as a subview so that it works like this:
(image at http://www.manna-soft.com/test/uploads/UIImagePickerView-portrait.jpg)
This works fine until the iPad2 come into place... it autorotates like this and ruin the layout:
(image at http://www.manna-soft.com/test/uploads/UIImagePickerView-landscape.jpg)
The UIImagePickerController never rotates on iphone, ipod touch or the original iPad, but it does on iPad2.
the class reference of UIImagePickerContrller says that it "supports portrait mode only", but what happens is it autorotates like that....
Is there a way that I can disable the autorotation?
I tried returning NO in the method shouldAutorotateToInterfaceOrientation: of the view controller which the UIImagePickerController is presented, but it still rotates.
Thanks in advance.
You can compensate the rotation of your ipad by roatting the overlay view of your UIImagePickerController. Fisrt you have to capture the notifications using:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notificationCallback:) name:nil object:nil];
Then use this code:
- (void) notificationCallback:(NSNotification *) notification {
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
if ([[notification name] isEqualToString:@"UIDeviceOrientationDidChangeNotification"]) {
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
switch ( orientation ) {
case UIInterfaceOrientationLandscapeRight:
NSLog(@"LandcapeRight");
[UIView beginAnimations:@"LandscapeRight" context:UIGraphicsGetCurrentContext()];
[UIView setAnimationDuration:0.4];
m_uiCameraOverlayView.transform = CGAffineTransformIdentity;
[UIView commitAnimations];
break;
case UIInterfaceOrientationLandscapeLeft:
NSLog(@"LandscapeLeft");
[UIView beginAnimations:@"LandcapeLeft" context:UIGraphicsGetCurrentContext()];
[UIView setAnimationDuration:0.4];
m_uiCameraOverlayView.transform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(M_PI), 0, 0);
[UIView commitAnimations];
break;
case UIInterfaceOrientationPortraitUpsideDown:
NSLog(@"UpsideDown");
[UIView beginAnimations:@"UpsideDown" context:UIGraphicsGetCurrentContext()];
[UIView setAnimationDuration:0.4];
m_uiCameraOverlayView.transform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(-M_PI / 2), -128, -128);
[UIView commitAnimations];
break;
case UIInterfaceOrientationPortrait:
NSLog(@"Portrait");
[UIView beginAnimations:@"Portrait" context:UIGraphicsGetCurrentContext()];
[UIView setAnimationDuration:0.4];
m_uiCameraOverlayView.transform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(M_PI / 2), 128, 128);
[UIView commitAnimations];
break;
default:
NSLog(@"????");
break;
}
}
}
}
The overlay view can be added to the window, and thn the window.superview can be set as cameraOverlayView.
While dismissing the ModalController the overlay view can be removed from the window.
This solution can be a little tricky to apply depending on how your app is structured.
YourAppDelegate *appDelegate = (YourAppDelegate *) [[UIApplication sharedApplication] delegate];
[appDelegate.window addSubview:overlayView];
imagePickerController.cameraOverlayView = appDelegate.window.superview;
//When dismissing the UIImagePicker
[self dismissModalViewControllerAnimated:YES];
[OverlayView removeFromSuperview];
Because UIImagePickerController derives from UINavigationController which derives from UIViewController, you can check out at "Handling View Rotations" in the UIViewController doc to see if that info helps.
You will notice that when you do this:
UIImagePickerController *camera = [UIImagePickerController new];
NSLog([self.camera shouldAutorotate] ? @"YES" : @"NO");
The result will be YES. I think by default, it is set to YES.
You can subclass UIImagePickerController and add this method to override that method:
- (BOOL)shouldAutorotate{
return NO;
}
Then instead of using UIImagePickerController, use your created subclass.
UIImagePickerSubclass *camera = [UIImagePickerSubclass new];
Hope this helps :)