4

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.

Eric
  • 43
  • 1
  • 4
  • Did you happen to find a solution for this – Nash Apr 20 '11 at 13:26
  • I did something similar to MarcVivet's suggestion, make a reversed animation to counter the autorotation. I think I will try ur solution later because it seems neater to do it this way (I don't have the ipad2 to try right now). – Eric Apr 27 '11 at 11:28

4 Answers4

5

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]; 
Nash
  • 201
  • 2
  • 9
  • I never thought about this... if I add a subview on the window, is it that it will never be rotated (because the window does not rotate)? – Eric Apr 27 '11 at 11:26
  • This solution worked for me, but the MarcVivet's above did not. Thanks! – Brian Robbins Jun 02 '11 at 23:09
0

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

aalesano
  • 357
  • 2
  • 13
0

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.

Todd Hopkinson
  • 6,803
  • 5
  • 32
  • 34
  • i've tried subclassing UIImagePickerController and override the method shouldAutorotateToInterfaceOrientation: so that it return YES only if it is portrait mode ... but it doesn't work, the method prints something to the console when it is called, and i found that the method is never called at all.... any idea why is it like this? – Eric Apr 18 '11 at 10:58
-3

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;
        }
    }
 }
}
MarcVivet
  • 10
  • 1
  • This is what I'm doing right now, athough the code is long, it does the job for me. Instead of using the notification center, I implemented the code in the willRotateToInterfaceOrientation:duration: method so that i know exactly the time it should takes to do the rotation. – Eric Apr 27 '11 at 11:23
  • I tried this with your suggestion and with Eric's, but neither method worked. On iPad 2 I get a LOT of UIDeviceOrientationDidChangeNotifications, at least 2 every time it rotates and the rotation never kept up properly. – Brian Robbins Jun 02 '11 at 23:10
  • This code is only for landscape right if you would like to use Portrait mode you must change the transformation ... ¬_¬ – MarcVivet Jun 03 '11 at 07:42