在UIImagePicker中禁用旋转

时间:2012-04-09 12:53:32

标签: iphone objective-c ios5 uiimagepickercontroller

您好我需要禁用UIImagePicker的旋转 如果用户在iPhone处于“风景”时拍照,则按钮将旋转并且拍摄的照片也将旋转。我想禁用该选项,因此加速度计将无法工作,并且它将始终像纵向模式一样拍摄 我怎么能这样做?
谢谢,Matan Radomski。

4 个答案:

答案 0 :(得分:28)

以下是解决方案:[UIDevice endGeneratingDeviceOrientationNotifications]

为什么这么难找?有两个原因:

  1. UIDevice会计算打开或关闭方向通知的次数。如果它已被打开的时间超过关闭时间,则仍会发出通知。
  2. UIImagePickerController会在呈现时切换这些通知。
  3. 因此,调用此方法一次对图像选择器没有任何作用。要确保方向通知处于关闭状态且保持关闭,您需要在呈现选择器之后在之前将其关闭。

    这不会影响iOS或其他应用。它甚至不会完全影响您自己的应用程序:与我建议的其他方法一样,相机按钮会继续响应方向更改,并且拍摄的照片也可以识别方向。这很奇怪,因为如果不需要,应该关闭设备方向硬件。

    @try 
    {
        // Create a UIImagePicker in camera mode.
        UIImagePickerController *picker = [[[UIImagePickerController alloc] init] autorelease]; 
        picker.sourceType = UIImagePickerControllerSourceTypeCamera;  
        picker.delegate = self; 
    
        // Prevent the image picker learning about orientation changes by preventing the device from reporting them.
        UIDevice *currentDevice = [UIDevice currentDevice];
    
        // The device keeps count of orientation requests.  If the count is more than one, it continues detecting them and sending notifications.  So, switch them off repeatedly until the count reaches zero and they are genuinely off.
        // If orientation notifications are on when the view is presented, it may slide on in landscape mode even if the app is entirely portrait.
        // If other parts of the app require orientation notifications, the number "end" messages sent should be counted.  An equal number of "begin" messages should be sent after the image picker ends.
        while ([currentDevice isGeneratingDeviceOrientationNotifications])
            [currentDevice endGeneratingDeviceOrientationNotifications];
    
        // Display the camera.
        [self presentModalViewController:picker animated:YES];
    
        // The UIImagePickerController switches on notifications AGAIN when it is presented, so switch them off again.
        while ([currentDevice isGeneratingDeviceOrientationNotifications])
            [currentDevice endGeneratingDeviceOrientationNotifications];
    }
    @catch (NSException *exception) 
    {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"No Camera" message:@"Camera is not available" delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil];
        [alert show];
        [alert release];
    }
    

    如上所述,拍摄的照片可能仍然处于错误的方向。如果您希望它们一致地定向,请检查它们的纵横比并相应地旋转。我推荐this answer to How to Rotate a UIImage 90 degrees?

    //assume that the image is loaded in landscape mode from disk
    UIImage * landscapeImage = [UIImage imageNamed: imgname];
    UIImage * portraitImage = [[UIImage alloc] initWithCGImage: landscapeImage.CGImage scale:1.0 orientation: UIImageOrientationLeft] autorelease];
    

答案 1 :(得分:3)

早在2010年,How to prevent a modal UIImagePickerController from rotating?找不到这个问题的快乐答案。

我找到了一个替代方案,但它也让你从App Store中被拒绝:从窗口中移除所有观察者。

如果你的应用程序在viewController之外的某些部分需要方向更改消息,它可以注册它们:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationChanged:) name:UIDeviceOrientationDidChangeNotification object:[UIDevice currentDevice]];

窗口毫不奇怪地注册了这样的通知,然后如果它们接受新的方向,则旋转视图控制器。它并不方便地观察UIDeviceOrientationDidChangeNotification,所以必须有一个私人命名的等价物。您所能做的就是从窗口中删除每个通知:

[[NSNotificationCenter defaultCenter] removeObserver:[[self view] window]];

如果您只想暂时禁止方向更改,则无法恢复此功能。我们也无法判断窗口是否正在监视来自其他来源的任何重要通知。它也是不完整的 - 用于翻转的按钮,以及用于拍照,移动和旋转的按钮。

Screenshot of iPad in landscape mode with camera UI still in portrait

你怎么能解决那个怪癖?您可以关闭UIImagePicker上的showsCameraControls,并为您自己的cameraOverlayView提供相机按钮。或者通过遍历整个视图层次结构(也是拒绝材料)从所有内容中删除通知来继续随机删除通知:

- (void) removeAllNotificationsFromView:(UIView*) view;
{
    // This recurses through the view hierarchy removing all notifications for everything.
    // This is potentially destructive, and may result in rejection from the App Store.
    [[NSNotificationCenter defaultCenter] removeObserver:view];
    for (UIView *subview in [view subviews])
        [self removeAllNotificationsFromView:subview];
}

[self removeAllNotificationsFromView:imagePicker.view];

我不建议使用此功能,但它提供了一些有关如何检测和传播方向更改的有趣见解。

答案 2 :(得分:1)

以上解决方案均不适合我。这是有用的(对于iOS 7,我测试过它) -

  1. 子类UIImagePickerController

  2. 覆盖shouldAutorotate方法并返回NO

  3.     -(BOOL)shouldAutorotate
        {
            return NO;
        }
    

答案 3 :(得分:-3)

在视图中添加以下代码

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 
{
     return NO;
}