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);
}
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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With