6

I have an UIPopoverController that presents an UIViewController using this method:

[self.popover presentPopoverFromBarButtonItem:self.infoBarButtonItem 
                     permittedArrowDirections:UIPopoverArrowDirectionUp
                                     animated:YES];

self.popover is my UIPopoverController.

The code works well, but the Popover arrow is in the middle of the BarButtonItem how do I display the Popover with its arrow "under" the button?

This is what it currently looks like:
altText

lukas
  • 2,300
  • 6
  • 28
  • 41

6 Answers6

16

In iOS 9 you can try this code:

let alert = UIAlertController(title: "title", message: "message", preferredStyle: UIAlertControllerStyle.ActionSheet)
alert.modalPresentationStyle = UIModalPresentationStyle.Popover
alert.popoverPresentationController?.barButtonItem = sender
presentViewController(alert, animated: true, completion: nil)
A.Gao
  • 161
  • 1
  • 5
  • Hey, welcome to Stack Overflow! Don't forget to format your code snippets using a 4-space indent, to make it look nicer. – Jolta Nov 16 '15 at 08:32
  • @StudentT Sorry that's a UIAlertController. Answer edited. – A.Gao Nov 24 '15 at 15:12
  • As of this writing, note that the `barButtonItem` property of a `UIPopoverPresentationController` is deprecated in iOS 16. You should switch to `sourceItem` if possible. https://developer.apple.com/documentation/uikit/uipopoverpresentationcontroller/1622314-barbuttonitem – Cem Schemel Oct 16 '22 at 20:41
7

How about this

UIBarButtonItem *item = self.infoBarButtonItem ;

UIView *view = [item valueForKey:@"view"];

if(view){

        CGRect frame=view.frame;

        [self.popover presentPopoverFromRect:frame
                                      inView:view.superview
                    permittedArrowDirections:UIPopoverArrowDirectionUp
                                    animated:YES];



}
4

For all who are using UIViewController with PopoverPresentationController (iOS 9+); This worked for me: you can directly set your UIBarButtonItem like this.

myPopoverPresentationController?.barButtonItem = myUIBarButtonItem
luke8800gts
  • 398
  • 3
  • 7
0

My recommendation would be to use the method:

presentPopoverFromRect:inView:permittedArrowDirections:animated:

and give it an appropriate CGRect to make the UIPopoverController appear where you would like.

You could then specify exactly where you'd like the popover to originate and point to. This is not an ideal situation, but when it come to giving the popover controller a UIBarButtonItem, you have no say as to how it should use it to position itself.

Infinity James
  • 4,667
  • 5
  • 23
  • 36
0

Try this in the selector method of the info button :

[self.popover presentPopoverFromRect:[(UIButton *)sender frame]
                                         inView:self.view
                       permittedArrowDirections:UIPopoverArrowDirectionUp
                                       animated:YES];

Hope this helps you!

Mahesh
  • 526
  • 1
  • 6
  • 21
0

It can be done by using this code.

In Swift

 if UIDevice.current.userInterfaceIdiom == .pad {
    let item = self.navigationItem.rightBarButtonItem;
    let view = item?.value(forKey: "view")
    let popPresenter = alert.popoverPresentationController
    popPresenter?.sourceView = view
    popPresenter?.sourceRect = view.bounds
 }
 present(alert, animated: true, completion: nil)

In Objective-C

if([[UIDevice currentDevice]userInterfaceIdiom]== UIUserInterfaceIdiomPad) {
    UIBarButtonItem *item = self.navigationItem.rightBarButtonItem;
    UIView *view = [item valueForKey:@"view"];
    UIPopoverPresentationController *popover = alert.popoverPresentationController;
    if(view){
       popover.sourceRect = view.frame;
       popover.sourceView = view;
    }
 }
Sunny
  • 821
  • 6
  • 17