Crash on presenting UIImagePickerController under iOS 6.0
Asked Answered
L

5

41

My app only supports landscape orientations via the supportedInterfaceOrientation properties.

Using an iOS prior to iOS 6, my app can successfully load an instance of UIImagePickerController via presentViewController:animated:completion: even though the UIImagePickerController itself only supports portrait orientation.

The image picker simply presented itself sideways to the user. The user rotated the phone, picked their image, and then rotated back to landscape.

Under iOS 6.0, calling presentViewController:animated:completion: with the UIImagePickerController instance crashes the app. I can prevent the crash by adding portrait options to my supportedInterfaceOrientation properties.

However, operating in portrait really does not make sense for my app. I had thought I could use shouldAutorotateToInterfaceOrientation to allow the app to "support portrait" but only be allowed to rotate to portrait in this one view. But now that method is deprecated, and I can't use the same technique with shouldAutorotate.

Does anyone have any ideas how I can get around this issue under iOS 6.0?

Liquesce answered 20/9, 2012 at 23:43 Comment(5)
BTW, as I've been investigating this, I compiled and ran the sample code "Popovers" and it executes perfectly in all orientations under Xcode 4.5 and iOS 6 Simulator, so I think this is bug in UIImagePicker when the supported orientation mask is not All. Planning to file a bug if I can somehow prove this ;-)Yang
Please see my answer for explanations of this bugTrypsin
A lot of people are using the solution of subclassing UIImagePickerController, this is really not the way to do this. May I bring your attention to the Apple documentation which specifically notes: The UIImagePickerController class supports portrait mode only. This class is intended to be used as-is and does not support subclassing please review my answer here with an Apple approved solution: https://mcmap.net/q/162901/-crash-on-presenting-uiimagepickercontroller-under-ios-6-0Trypsin
Apple fixed this bug in iOS 6.1, please check out this answer for the workaround: https://mcmap.net/q/162901/-crash-on-presenting-uiimagepickercontroller-under-ios-6-0Trypsin
This answer also helped me fix orientation crash when game center login dialog tried to popup when my game was beginning. The game never crashed when you are already logged into GC. But when you logout outside the game and start the game, then it was crashing, The top answer helped me fix it.Blighter
T
80

iOS 6.1 - fixed

As of iOS 6.1, this no longer occurs, it is very important to follow my tips in order to avoid a crash under iOS 6.0.x, the below still applies to that.


iOS 6.0.x workaround

This is in actual fact a bug in iOS 6.0, this should be fixed in future iOS releases.

An engineer from Apple has explained this bug and a workaround here: https://devforums.apple.com/message/731764

This is happening because the Application wants landscape orientation only but some Cocoa Touch View Controllers require strictly Portrait orientation which is the error - not that they should be requiring more then Portrait but their interpretation of the Applications requirements.

An example of this can be the following:

iPad app supporting landscape only displays a UIImagePickerController via a UIPopoverController. The UIImagePickerController requires Portrait orientation, but the app is forcing landscape only. Error and... crash

Other frameworks that have been reported as problematic include the Game Center login view controller.

The workaround is pretty simple but not ideal... You keep the correct orientations declared in your info.plist/project info pane, but in the Application Delegate class you declare that you allow all orientations.

Now each View Controller you add to the window must specify itself that it can only be Landscape. Please check the link for more details.


I cannot stress how much you should not be subclassing UIImagePickerController as the accepted solution is insisting you do.

enter image description here

The important thing here is "This class is intended to be used as-is and does not support subclassing."


In my case I added this to my application's delegate (I have a landscape only app), this tells the image picker it can display, because portrait is supported:

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

And then in my view controller which happened to be a UINavigationController, I included a category with the following:

- (NSUInteger)supportedInterfaceOrientations{
    return UIInterfaceOrientationMaskLandscape;
}

Now my app doesn't rotate, and the image picker asks the delegate if it can display as portrait and it gets told that's okay. So all plays out well.

Trypsin answered 25/9, 2012 at 1:24 Comment(3)
Just for clarification, I added this method to my AppDelegate.m -(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window { return UIInterfaceOrientationLandscapeRight | UIInterfaceOrientationLandscapeLeft; }Acerbity
None of this worked for me. Sure the popover displays correctly, but now my app will rotate to whatever orientation it pleases, including portrait which I definitely don't want. What do I do to fix this?Semiweekly
It sounds like you are not setting up the navigation controller tip correctly. The app delegate is going to say its okay for all rotations, but your root view controller (your container controller) must then restrict it to only landscape. If you're app is rotating all orientations then its the last part you've done wrong.Trypsin
C
41

I had a similar issue, but in an iPad landscape app. I was presenting the image picker in a popover. It crashed under iOS 6. The error suggested that the picker wanted portrait, but the app only offered landscape views, and ... importantly ... the picker's shouldRotate was returning YES.

I added this to my ViewControllerClass.m that is creating the picker

@interface NonRotatingUIImagePickerController : UIImagePickerController

@end

@implementation NonRotatingUIImagePickerController

- (BOOL)shouldAutorotate
{
    return NO;
}

@end

and then used that class instead

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

That solved the problem for me. Your situation is a bit different, but it sounds like fundamentally the same error.

Chasidychasing answered 21/9, 2012 at 3:39 Comment(6)
Worked perfectly for me. Thanks so much!Liquesce
I ran into the same exact problem, so upvote on the question and upvote on the answer! What are you setting for your supportedInterfaceOrientationsForWindow: ? I was returning UIInterfaceOrientationLandscapeLeft | UIInterfaceOrientationLandscapeRight but that's causing my app to launch in portrait! Info-Plist is showing both landscape left and landscape rightYang
FIXED By returning UIInterfaceOrientationMaskLandscape and setting shouldAutorotate to return NO, my app now launches in landscape and the viewcontroller which presents the imagepicker doesn't crash.Yang
Subclassing UIImagePickerController is really not the way to do this. May I bring your attention to the Apple documentation which specifically notes: The UIImagePickerController class supports portrait mode only. This class is intended to be used as-is and does not support subclassing please review my answer here with an Apple approved solution: https://mcmap.net/q/162901/-crash-on-presenting-uiimagepickercontroller-under-ios-6-0Trypsin
Don't bother UIImagePickerController -- just use a category to achieve the same result, it's way easier too. https://mcmap.net/q/162812/-supported-orientations-has-no-common-orientation-with-the-application-and-shouldautorotate-is-returning-yes-39Obe
Apple fixed this bug in iOS 6.1, please check out this answer for the workaround: https://mcmap.net/q/162901/-crash-on-presenting-uiimagepickercontroller-under-ios-6-0Trypsin
M
26

While subclassing UIImagePickerController works, a category is a better solution:

    @implementation UIImagePickerController (NonRotating)

    - (BOOL)shouldAutorotate
    {
        return NO;
    }

    -(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
    {
        return UIInterfaceOrientationPortrait;
    }

    @end
Monegasque answered 24/9, 2012 at 18:12 Comment(1)
Why was this answer down voted? In a slightly different situation with my portrait mode only app I found that adding a category with: [at]implementation UINavigationController(landscape) - (BOOL)shouldAutorotate { return YES; } - (NSUInteger)supportedInterfaceOrientations { return UIInterfaceOrientationMaskLandscapeRight|UIInterfaceOrientationMaskLandscapeLeft; } - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation { return UIInterfaceOrientationLandscapeRight; } [at]end to my app delegate and then selecting the all orientations under Summary, it fixed it.Rosenberg
P
1

Reporting from iOS 7.1:

In addition to what the above answers specify it seems that you have to absolutely enable portrait modes in the info.plist.

Without this none of the above code/fixes worked for me.

Pother answered 20/3, 2014 at 9:44 Comment(0)
W
1
-(NSUInteger)supportedInterfaceOrientations
{
   return UIInterfaceOrientationMaskLandscape;
}

Will fix the issue but from iOs7

Wafer answered 1/7, 2014 at 11:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.