Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"Attempt to present Xamarin_Forms_Platform_iOS_ModalWrapper whose view is not in the window hierarchy" error with UIImagePickerController

I have an Xamarin.Forms-based app which runs on Android and iOS. Right now, I am implementing the feature of selecting images from the camera roll and uploading it to our server. Therefore, I am writing platform-specific code for iOS, which is where the error occurs.

I am calling the UIImagePickerController from a platform-specific renderer for iOS. It opens normally. But when tapping on an image in the UIImagePickerController nothing happens, except Visual Studio showing a message in the debug console:

"Warning: Attempt to present Xamarin_Forms_Platform_iOS_ModalWrapper: 0x155a7ed00 on Xamarin_Forms_Platform_iOS_PlatformRenderer: 0x153ead6a0 whose view is not in the window hierarchy!"

I googled and found somebody writing a function called "GetVisibleViewController" which i adapted to my project (you can see it below). On the ViewController which that function returns, I call the PresentModalViewController() method. Unfortunately, it is not working either. It is not possible to select a photo.

private void ChoosePhoto()
{
    _imagePicker = new UIImagePickerController()
    {
        SourceType = UIImagePickerControllerSourceType.PhotoLibrary,
        MediaTypes = new string[] { UTType.Image }
    };

    _imagePicker.FinishedPickingMedia += delegate (object sender, UIImagePickerMediaPickedEventArgs e)
    {
        var fileName = eopAppLibrary.Tools.GetTimestampJpegFileName("ScanToEop_iOS");
        var jpegImageData = e.OriginalImage.AsJPEG();
        var jpegBytes = jpegImageData.ToArray();

        Events.RaiseFilePreviewNeeded(this, jpegBytes, fileName);
    };

    _imagePicker.Canceled += delegate (object sender, EventArgs e)
    {
        _imagePicker.DismissModalViewController(true);
    };

    var viewController = GetVisibleViewController();
    viewController.PresentModalViewController(_imagePicker, true);
}
UIViewController GetVisibleViewController(UIViewController controller = null)
{
    controller = controller ?? UIApplication.SharedApplication.KeyWindow.RootViewController;

    if (controller.PresentedViewController == null)
    {
        return controller;
    }

    if (controller.PresentedViewController is UINavigationController)
    {
        return ((UINavigationController)controller.PresentedViewController).VisibleViewController;
    }

    if (controller.PresentedViewController is UITabBarController)
    {
        return ((UITabBarController)controller.PresentedViewController).SelectedViewController;
    }

    return GetVisibleViewController(controller.PresentedViewController);
}
like image 750
Sebastian Avatar asked Nov 06 '22 17:11

Sebastian


1 Answers

We had a similar issue and here is what we came up with:

    var topViewController = UIApplication.SharedApplication.KeyWindow.RootViewController;
    var controllerToPresentWith = topViewController.VisibleViewController();
    controllerToPresentWith.PresentModalViewController(_imagePicker, true);

and then

    ...
    public static UIViewController VisibleViewController(this UIViewController controller)
    {
        if (controller == null)
            return null;

        if (controller is UINavigationController navController)
        {
            return navController.VisibleViewController();
        }
        else if (controller is UITabBarController tabController)
        {
            tabController.SelectedViewController?.VisibleViewController();
        }
        else
        {
            var vc =  controller.PresentedViewController?.VisibleViewController();
            if (vc != null)
                return vc;
        }
        return controller;
    }
like image 138
Alex Sorokoletov Avatar answered Nov 11 '22 17:11

Alex Sorokoletov