Joseph
Joseph

Reputation: 963

Xamarin.iOS UIPopoverPresentationController Exception

I am having difficulty presenting a Popover with UIPopoverPresentationController, following what can I find from the internet, including this and this. Nothing has helped. Here's a test app I created:

ViewController.cs

  public override void ViewDidLoad()
  {
     ...

     var popupView = new UIImageView(new CGRect(0, 0, 200, 200))
     {
        Image = UIImage.FromBundle("Menu")
     };

     _menuController = new UIViewController
     {
        ModalPresentationStyle = UIModalPresentationStyle.Popover,
        View = popupView
     };

     _presentationController = new UIPopoverPresentationController(_menuController, this)
     {
        SourceView = View,
        SourceRect = new CGRect(50, 50, 300, 300),
     };
  }

And I invoke on button press with:

  PresentViewController(_menuController, true, null);

I get this exception when the presentation style is Popover:

UIPopoverPresentationController should have a non-nil sourceView or barButtonItem set before the presentation occurs.

Upvotes: 0

Views: 1655

Answers (2)

Ax1le
Ax1le

Reputation: 6643

Every UIViewController has a UIPopoverPresentationController called PopoverPresentationController, you can just use that to present your pop view:

private void OnMenuSelected(object sender, EventArgs eventArgs)
{
    var popupView = new UIImageView(new CGRect(0, 0, 200, 200))
    {
        Image = UIImage.FromBundle("Menu"),
        UserInteractionEnabled = true
    };

    _menuController = new UIViewController
    {
        ModalPresentationStyle = UIModalPresentationStyle.Popover,
        PreferredContentSize = new CGSize(200, 200),
        View = popupView
    };

    _menuController.PopoverPresentationController.SourceRect = new CGRect(50, 50, 300, 300);
    _menuController.PopoverPresentationController.SourceView = View;


    PresentViewController(_menuController, true, null);
}

I find that when we dismiss the popoverview, it will return to null. So here I recommend you to initialize it in your method every time when you show it up.

Moreover if you want to achieve the same effect on iPhone, please add the UIPopoverPresentationControllerDelegate like:

public override UIModalPresentationStyle GetAdaptivePresentationStyle(UIPresentationController forPresentationController)
{
    return UIModalPresentationStyle.None;
}

Set the delegate to it: _menuController.PopoverPresentationController.Delegate = new MyPopOverViewDelegate();

Upvotes: 2

SushiHangover
SushiHangover

Reputation: 74144

You need to set the UIPopoverPresentationController.SourceView to a UIView that is outside the view controller to provide a view that becomes the anchor point, i.e. a UIView on the parent view controller

You say present this via a button touch, you could use that button as the source (if that location is appropriate).

_presentationController = new UIPopoverPresentationController(_menuController, this)
{
    SourceView = button,
    SourceRect = new CGRect(50, 50, 300, 300),
};

Example:

enter image description here

Upvotes: 0

Related Questions