9

我的应用程序仅在横向模式下运行!所以我知道UIImagePickerController只在纵向模式下呈现,所以在 iOS 6 中,我创建了一个UIImagePickerController强制UIImagePickerController以纵向模式打开的子类:

@interface NonRotatingUIImagePickerController : UIImagePickerController

@end

@implementation NonRotatingUIImagePickerController

- (BOOL)shouldAutorotate {

    return NO;
}

@end

//presenting picker controller :

UIImagePickerController *ipc = [[NonRotatingUIImagePickerController alloc]init];
ipc.delegate = self;
[self presentViewController:ipc animated:YES completion:nil];

这在 iOS 6 中运行良好,但现在在 iOS 7 中,我的应用程序确实因为以下原因而崩溃:

2013-10-31 14:56:01.028 Medad[1731:60b] *** Terminating app due to
uncaught exception 'UIApplicationInvalidInterfaceOrientation', reason:
'Supported orientations has no common orientation with the
application, and shouldAutorotate is returning YES'

Portrait如果我签入部署信息, 则可以解决此问题:在此处输入图像描述

问题是,如果我选中此选项,我的应用程序也会纵向运行,但我不想要它!

我该如何解决这个问题?

4

6 回答 6

6

我已经对其进行了测试,发现您不应该通过目标窗口中的复选框来处理方向,如上图所示,因为它是您的整个应用程序方向,因此请选中所有框以支持所有方向。如果你想要一些不同方向的视图和一些不同的视图,那么你将不得不通过在ViewController类中通过返回YESOR来处理它来处理它NO

这是我的示例。我做的。请检查。

下面的方法将处理方向ViewController

-(BOOL)shouldAutorotate
{
    return YES;
}

-(NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight;
}

// Old Method
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
    if (UIInterfaceOrientationIsPortrait(toInterfaceOrientation)) {
     return NO;
    }
    else {
        return YES;
    }
}

因此,解决方案是:创建两个自定义类,一个用于UIImagePickerController,另一个用于ViewController(对于所有 ViewControllers),并将它们用于特定方向,并将这些类分别用作您UIImagePickerController和所有人的超类ViewControllers

于 2013-11-07T12:52:10.037 回答
1

有一种简单的解决方案可以避免更改应用程序支持的方向,并使UIImagePickerController工作正常:UIInterfaceOrientationMaskAll仅在必须呈现选择器时才返回。

您可以简单地继承 UIApplication 并使用以下两种方法:

- (NSUInteger)supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
    UIViewController *topController = window.rootViewController;

    if ([self hasPicker:topController])
        return UIInterfaceOrientationMaskAll;

    return [super supportedInterfaceOrientationsForWindow:window];
}

-(BOOL)hasPicker:(UIViewController *)controller
{
    BOOL hasPicker = NO;

    NSLog(@"Check Controller: %@", controller);

    if ([controller isKindOfClass:[UIImagePickerController class]])
        return YES;

    for (UIViewController *child in controller.childViewControllers) {
        hasPicker = [self hasPicker:child];

        if (hasPicker)
            return YES;
    }

    return NO;
}

在第一种方法中,您将覆盖默认supportedInterfaceOrientationsForWindows:方法。每次调用该方法时,您都会检查层次结构中的所有视图控制器(通过hasPicker:递归方法)。如果找到 UIImagePickerController,则返回UIInterfaceOrientationMaskAll,否则返回应用程序的默认设置。

我建议你的另一件事:不要 subclass UIImagePickerController,因为 Apple 明确禁止它。相反,像我在此示例中所做的那样使用视图控制器包含:

景观选择器示例

注意:示例代码仅适用于UIImagePickerController包含。如果您将其子类化并通过添加它,presentViewController:您可能必须调整该hasPicker:方法的行为。您可以做的另一件简单的事情是:向您的UIApplication子类添加一个实例变量,并在显示选择器时设置它,并在您关闭时取消设置

于 2013-11-08T19:41:43.927 回答
0

您还应该在子类中设置:

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
    return UIInterfaceOrientationLandscapeLeft ;
}

- (NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskLandscape;
}

- (BOOL)shouldAutorotate {
    return YES;
}

现在您可以从设置中删除“人像”

[编辑] 由于 UIImagePickerController 只能以纵向显示(根据 Apple 文档),因此可以反其道而行,启用纵向和横向方向,但固定除选取器控制器之外的所有东西的横向方向。我做了一个可以从这里下载的小样本。

于 2013-11-02T13:34:49.807 回答
0

在每个控制器中添加:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    if (interfaceOrientation == UIInterfaceOrientationLandscapeLeft
        || interfaceOrientation == UIInterfaceOrientationLandscapeRight)
    {
        return YES;
    }
    return NO;
}

- (BOOL)shouldAutorotate {
    return YES;
}

- (NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskLandscape;
}

对于你有选择器的控制器:设计这个视图只有纵向方向。因此,它将具有与选择器相同的方向。此视图将是唯一的纵向视图,而其他视图为横向。

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    if (interfaceOrientation == UIInterfaceOrientationPortrait)
    {

        return YES;
    }

    return NO;
}

- (BOOL)shouldAutorotate {

    UIInterfaceOrientation orientation = [[UIDevice currentDevice] orientation];

    if (orientation==UIInterfaceOrientationPortrait) {

    }

    return YES;
}

- (NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskPortrait;
}

其他解决方案也将在具有选择器的视图中崩溃,因为它们不会返回纵向来处理选择器方向。虽然不向此视图控制器添加任何代码将使此视图以横向和纵向运行。

因此,我提出的解决方案是在横向运行所有视图,而在纵向运行这个视图。以纵向显示此视图更符合设计逻辑,以使选择器具有相同的方向。

以下内容进入您的自定义选择器:

 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
    {
        if (interfaceOrientation == UIInterfaceOrientationPortrait)
        {
            return YES;
        }

        return NO;
    }

    - (BOOL)shouldAutorotate {
        return YES;
    }

    - (NSUInteger)supportedInterfaceOrientations {
        return UIInterfaceOrientationMaskPortrait;
    }
于 2013-11-02T13:40:39.010 回答
0

另一种解决方案。

在每个控制器中添加,甚至添加到具有选择器的控制器:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    if (interfaceOrientation == UIInterfaceOrientationLandscapeLeft
        || interfaceOrientation == UIInterfaceOrientationLandscapeRight)
    {
        return YES;
    }
    return NO;
}

- (BOOL)shouldAutorotate {
    return YES;
}

- (NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskLandscape;
}

将此添加到您的自定义选择器控制器:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    if (interfaceOrientation == UIInterfaceOrientationPortrait)
    {
        return YES;
    }

    return NO;
}

- (BOOL)shouldAutorotate {
    return YES;
}

- (NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskPortrait;
}
于 2013-11-02T14:15:44.880 回答
0

实际上我遇到了同样的问题并以不同的方式解决了它...实际上这被确定为 IOS6 中的一个错误发生在 ImageViewController 中,它只支持纵向方向...所以我花了很多时间并找到了解决方法。 ...

希望这会有所帮助,所以首先...

在 AppDelegate.h 中添加一个属性

@property BOOL model;

然后在 AppDelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Override point for customization after application launch.
    self.model=NO;

    return YES;
}

也在 AppDelegate.m 中添加这个方法

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{

    if(!self.model)
        return  UIInterfaceOrientationMaskLandscape; //or needed orientation
    else

        return UIInterfaceOrientationMaskAllButUpsideDown;


}

然后在您的视图控制器中呈现图像选择器之前

实现此代码...

AppDelegate *appdelegate=(AppDelegate*)[[UIApplication sharedApplication] delegate];
            appdelegate.model=YES;

然后你只需在选择图像后返回时更改值,即委托方法

AppDelegate *appdelegate=(AppDelegate*)[[UIApplication sharedApplication] delegate];
            appdelegate.model=NO;
于 2013-11-07T12:29:27.247 回答