TheSnakeWizard
TheSnakeWizard

Reputation: 59

UIImagePickerController not showing up in xamarin iOS

For some odd reason is my UIImagePickerController not showing up running this code ? Can you see the problem ?

this is on my Iphone 5 - I only get a black screen appearing - and I cannot do any interaction

var pictureViewer = new PictureViewController((APTask)GetItem(e.IndexPath.Row), e.IndexPath);
parent.NavigationController.PresentViewController(pictureViewer, true, null);

This is picture classview class:

public class PictureViewController : UIViewController, IUINavigationControllerDelegate
{
    private UIImagePickerController _imagePicker;
    private APTask _task;
    private NSIndexPath _indexPath;
    private UIImage _image;
    private NSDictionary _imageMetadata;

    public PictureViewController(APTask task, NSIndexPath indexPath)
    {
        this._task = task;
        this._indexPath = indexPath;
    }


    public override void ViewDidLoad()
    {
        base.ViewDidLoad();

        _imagePicker = new UIImagePickerController ();

        // set our source to the photo library
        _imagePicker.SourceType = UIImagePickerControllerSourceType.Camera;

        _imagePicker.ModalPresentationStyle = UIModalPresentationStyle.CurrentContext;
        // set what media types
//      _imagePicker.MediaTypes = UIImagePickerController.AvailableMediaTypes (UIImagePickerControllerSourceType.PhotoLibrary);

        _imagePicker.FinishedPickingMedia += Handle_FinishedPickingMedia;
        _imagePicker.Canceled += Handle_Canceled;

        _imagePicker.Delegate = this;

        PresentViewController(_imagePicker, true, null);

    }

Upvotes: 0

Views: 1408

Answers (1)

SushiHangover
SushiHangover

Reputation: 74174

You would need to present the UIImagePickerController at the competition of presenting your pictureViewer as it is a UIViewController

Your code:

parent.NavigationController.PresentViewController(pictureViewer, true, null);

Would need to not pass null for the competition handler. You could expose a pubic method on your PictureViewController class that does the creation/presentation of the UIImagePickerController and pass that Action (method) as the handler...

But why create/present an empty UIViewController just to than cover it up with a UIImagePickerController, here is how I do it...

Note: This code also handles iPad presentation properly and if you are requesting the camera within the Simulator it defaults to the PhotoLibrary to avoid the native ObjC exception.

public partial class myViewController : UIViewController
{
    UIImagePickerController _imagePickerController;

    public myViewController (IntPtr handle) : base (handle) { }

    partial void myButtonTouch(UIButton sender)
    {
        ImagePickerController(UIImagePickerControllerSourceType.Camera);
    }

    public void ImagePickerController(UIImagePickerControllerSourceType sourceType)
    {
        if (_imagePickerController == null)
            _imagePickerController = new UIImagePickerController();
        if (Runtime.Arch == Arch.DEVICE) // No camara on Simulator
            _imagePickerController.SourceType = sourceType;
        else
            if (sourceType == UIImagePickerControllerSourceType.Camera)
                _imagePickerController.SourceType = UIImagePickerControllerSourceType.PhotoLibrary;
        if (UIDevice.CurrentDevice.UserInterfaceIdiom == UIUserInterfaceIdiom.Pad) // Handle ipad correctly 
        {
            if (_imagePickerController.SourceType == UIImagePickerControllerSourceType.Camera)
                _imagePickerController.ModalPresentationStyle = UIModalPresentationStyle.FullScreen;
            else
                _imagePickerController.ModalPresentationStyle = UIModalPresentationStyle.Popover;
        }
        else
        {
            _imagePickerController.ModalPresentationStyle = UIModalPresentationStyle.CurrentContext;
        }

        _imagePickerController.Canceled += (object sender, EventArgs e) =>
        {
            Console.WriteLine("Picker Cancelled");
            _imagePickerController.DismissViewController(true, null);
        };
        _imagePickerController.FinishedPickingMedia += (object sender, UIImagePickerMediaPickedEventArgs e) =>
        {
            _imagePickerController.DismissViewController(true, null);
            Console.WriteLine(e.ReferenceUrl);
            if (_imagePickerController.SourceType == UIImagePickerControllerSourceType.Camera)
            {
                // Newly-captured media, save it to the Camera Roll on the device or ....
            }
            else
            {
                // Existing media seleted, do something with it....
            }
        };

        var mainWindow = UIApplication.SharedApplication.KeyWindow;
        var viewController = mainWindow?.RootViewController;
        while (viewController?.PresentedViewController != null)
        {
            viewController = viewController.PresentedViewController;
        }
        if (viewController == null)
            viewController = this;
        _imagePickerController.View.Frame = viewController.View.Frame;
        viewController.PresentViewController(_imagePickerController, true, () => { Console.WriteLine("Complete"); });
    }
}

Note: You can extract out the ImagePickerController method and add it to as static method somewhere to reuse as while (viewController?.PresentedViewController != null) code section will always find the correct context in which to present the modal controller.

Upvotes: 1

Related Questions