Search code examples
iosobjective-cuiimagepickercontroller

iOS 11 UIImagePickerController strange issue


I am using UIImagePickerController to select a single image from photo library. There is a strange issue on iPad when it is in landscape mode.

The image picker is presented using UIPopoverPresentationController on iPad as recommended. When it is first presented, the status bar is correct:

enter image description here

However, when going into the second level of the photo library, the status bar is changed to portrait mode:

enter image description here

What I have noticed so far are:

  1. This issue only appears in iOS 11, not iOS 10.
  2. When it happens, rotate the iPad to portrait and back to landscape will fix the status bar orientation.
  3. It only happened the first time presenting the picker controller.
  4. If ignore, presenting other modal view will be in portrait mode:

enter image description here

The code that presenting the uiimagepickerController is as follow:

    UIImagePickerController *picker = [[UIImagePickerController alloc] init];
    picker.modalPresentationStyle = UIModalPresentationPopover;
    picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
    picker.delegate = self;

    [self presentViewController:picker animated:YES completion:nil];

    UIPopoverPresentationController *popupController = picker.popoverPresentationController;
    if (popupController) {
        popupController.barButtonItem = sender;
    }

Any idea what have I done wrong, or it is a bug?

Whole example project can be downloaded here: https://www.dropbox.com/s/zgipclyr0mz26c6/test.zip?dl=0


Solution

  • I have finally found the cause of my issue.

    My app needs to support all orientation on iPad and Portrait mode only on iPhone. Therefore I added the following code of UIApplicationDelegate:

    - (UIInterfaceOrientationMask) application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
        if (window.traitCollection.userInterfaceIdiom == UIUserInterfaceIdiomPad) {
            return UIInterfaceOrientationMaskAll;
        }
    
        return UIInterfaceOrientationMaskPortrait;
     }
    

    But sometimes it gives me nil window, as in the case of UIImagePickerController presented using UIPopoverPresentationController on iPad, and will return UIInterfaceOrientationMaskPortrait and cause the status bar rotates to portrait mode. I have also noticed that this happens only when UIRequiresFullScreen is checked.

    I have solved my issue by checking that window is not nil as below:

    - (UIInterfaceOrientationMask) application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
        if (window) {
            if (window.traitCollection.userInterfaceIdiom == UIUserInterfaceIdiomPad) {
                return UIInterfaceOrientationMaskAll;
            } else {
                return UIInterfaceOrientationMaskPortrait;
            }
        } else {
            return UIInterfaceOrientationMaskAll;
        }
     }