iOS 6.0下在展示UIImagePickerController时崩溃问题

41

我的应用程序通过支持的 supportedInterfaceOrientation 属性仅支持横向方向。

在 iOS 6 之前的版本中,即使 UIImagePickerController 本身仅支持纵向方向,我的应用程序也可以通过 presentViewController:animated:completion: 成功加载一个实例。

图像选择器只是以侧向方式呈现给用户。 用户旋转手机,选择他们的图像,然后再旋转回横向。

在 iOS 6.0 下,使用 UIImagePickerController 实例调用 presentViewController:animated:completion: 会导致应用程序崩溃。我可以通过将纵向选项添加到我的 supportedInterfaceOrientation 属性中来防止崩溃。

然而,对于我的应用程序来说,使用纵向确实没有意义。 我曾经认为我可以使用 shouldAutorotateToInterfaceOrientation 允许应用程序“支持纵向”,但只允许在此视图中旋转到纵向。但现在该方法已被弃用,我不能使用相同的技术使用 shouldAutorotate。

有没有人有任何想法如何在 iOS 6.0 下解决这个问题?


顺便提一下,由于我一直在调查这个问题,我编译并运行了“弹出窗口”示例代码,在Xcode 4.5和iOS 6模拟器下的所有方向都能完美执行,因此我认为这是UIImagePicker中的一个错误,当支持的方向掩码不是全部时。如果我能证明这一点,计划提交一个错误报告;-) - tobinjim
请查看我的答案以了解此错误的解释。 - Daniel
1
很多人正在使用UIImagePickerController的子类解决方案,这真的不是正确的做法。我想提醒您注意苹果文档,其中明确指出:“UIImagePickerController类仅支持纵向模式。该类旨在按原样使用,不支持子类化”。请查看我的答案,其中包含了一个经过苹果认可的解决方案:https://dev59.com/6Gcs5IYBdhLWcg3w3HkG#12575058 - Daniel
苹果在iOS 6.1中修复了这个漏洞,请查看此答案以获取解决方法:https://dev59.com/6Gcs5IYBdhLWcg3w3HkG#12575058 - Daniel
这个答案还帮助我解决了方向崩溃的问题,当游戏中心登录对话框试图在我的游戏开始时弹出。当您已经登录到GC时,游戏从未崩溃。但是当您在游戏外注销并启动游戏时,它就会崩溃,顶部的答案帮助我解决了这个问题。 - Rajavanya Subramaniyan
5个回答

80

iOS 6.1 - 已修复

从iOS 6.1开始,这个问题已经得到解决。为了避免在iOS 6.0.x版本下崩溃,按照我的建议非常重要,以下内容仍然适用于该版本。


iOS 6.0.x 解决办法

实际上,这是iOS 6.0中的一个bug,在未来的iOS版本中应该会被修复。

苹果工程师已经在这里解释了这个bug以及解决方法。

出现这种情况是因为应用程序只想要横向方向,但一些Cocoa Touch视图控制器要求严格的纵向方向,这就是错误所在——并不是他们应该需要比纵向更多的方向,而是他们对应用程序需求的解释不正确。

这可能的一个示例是:

通过UIPopoverController显示UIImagePickerController的iPad应用程序只支持横向显示。UIImagePickerController需要纵向方向,但应用程序只允许横向,因此会发生错误和崩溃。

其他被报告有问题的框架包括Game Center登录视图控制器。

解决方法非常简单但不太理想......在info.plist/project info窗格中声明正确的方向,但在应用程序委托类中声明允许所有方向。

现在每个添加到窗口中的视图控制器都必须指定它只能是横向的。有关更多详细信息,请查看链接。


我无法强调你不应该子类化UIImagePickerController,因为接受的解决方案坚持要求你这样做。

enter image description here

重要的是,“这个类旨在原样使用,不支持子类化”。


在我的情况下,我将以下内容添加到我的应用程序委托(我有一个仅支持横向的应用程序),这告诉图片选择器可以显示,因为支持纵向:

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
    return UIInterfaceOrientationMaskAll;
}

然后在我的视图控制器中, 这个视图控制器碰巧是一个UINavigationController, 我包含了以下这个类别:

- (NSUInteger)supportedInterfaceOrientations{
    return UIInterfaceOrientationMaskLandscape;
}

现在我的应用程序不旋转,图像选择器询问代理是否可以以纵向显示,它被告知可以。所以一切都进行得很好。

1
仅供澄清,我将此方法添加到我的AppDelegate.m文件中 -(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window { 返回UIInterfaceOrientationLandscapeRight | UIInterfaceOrientationLandscapeLeft; } - Matt Hudson
2
这些对我都没用。虽然弹出视图正确显示了,但现在我的应用程序会旋转到任何方向,包括我绝对不想要的纵向。我该怎么办才能解决这个问题? - James
3
听起来你没有正确设置导航控制器提示。应用程序委托将会表明对所有方向的旋转都可以,但是你的根视图控制器(容器控制器)必须限制只能横屏。如果你的应用程序可以旋转所有方向,那么你就做错了最后一步。 - Daniel

41

我遇到了类似的问题,但是是在iPad横屏应用程序中。我将图像选择器展示在一个弹出窗口中,在iOS 6下崩溃了。错误提示表明选择器想要竖屏显示,但应用程序只提供横屏视图,并且...最重要的是...选择器的shouldRotate方法返回YES。

我在创建选择器的ViewControllerClass.m文件中添加了以下内容:

@interface NonRotatingUIImagePickerController : UIImagePickerController

@end

@implementation NonRotatingUIImagePickerController

- (BOOL)shouldAutorotate
{
    return NO;
}

@end

然后使用了那个类而不是之前的类

UIImagePickerController *imagePicker = [[NonRotatingUIImagePickerController alloc] init];
[myPopoverController setContentViewController:imagePicker animated:YES];

那对我来说解决了问题。你的情况有些不同,但听起来本质上是相同的错误。


2
对我来说完美地工作了。非常感谢! - jenonen
我遇到了完全相同的问题,所以在问题上投票并在答案上投票!你为supportedInterfaceOrientationsForWindow:设置了什么?我返回了UIInterfaceOrientationLandscapeLeft | UIInterfaceOrientationLandscapeRight,但这导致我的应用程序在纵向模式下启动!Info-Plist显示了左横向和右横向。 - tobinjim
通过返回UIInterfaceOrientationMaskLandscape并将shouldAutorotate设置为返回NO,我的应用现在以横向模式启动,并呈现图像选择器的视图控制器不会崩溃。 - tobinjim
3
子类化UIImagePickerController并不是实现这个目的的正确方法。我想提醒您注意苹果的文档,其中明确指出:“UIImagePickerController类仅支持纵向模式。此类应按原样使用,不支持子类化”。请查看我在这里给出的符合苹果规定的解决方案:https://dev59.com/6Gcs5IYBdhLWcg3w3HkG#12575058。 - Daniel
不要费心使用UIImagePickerController——只需使用分类即可实现相同的结果,而且更容易。https://dev59.com/KGcs5IYBdhLWcg3w1XbZ#12834354 - brack
苹果在iOS 6.1中修复了这个漏洞,请查看此答案的解决方法: https://dev59.com/6Gcs5IYBdhLWcg3w3HkG#12575058 - Daniel

26

虽然通过子类化UIImagePickerController可以实现,但使用分类是更好的解决方案:

    @implementation UIImagePickerController (NonRotating)

    - (BOOL)shouldAutorotate
    {
        return NO;
    }

    -(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
    {
        return UIInterfaceOrientationPortrait;
    }

    @end

为什么这个答案被踩了?在我的纵向模式应用程序的稍微不同的情况下,我发现添加以下类别可以解决问题:[at]implementation UINavigationController(landscape)
  • (BOOL)shouldAutorotate { return YES; }
  • (NSUInteger)supportedInterfaceOrientations { return UIInterfaceOrientationMaskLandscapeRight|UIInterfaceOrientationMaskLandscapeLeft; }
  • (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation { return UIInterfaceOrientationLandscapeRight; } [at]end
将其添加到我的应用程序委托中,并在摘要下选择所有方向即可解决问题。
- Nate Flink

1
-(NSUInteger)supportedInterfaceOrientations
{
   return UIInterfaceOrientationMaskLandscape;
}

将修复该问题,但从iOs7开始。


1

来自iOS 7.1的报告:

除了以上回答所指明的内容,似乎您必须在info.plist中绝对启用纵向模式。

如果没有这个设置,上述任何代码/修复都不会对我起作用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接