I am trying to center a popover on a button. I can't seem to figure out where I might be going wrong. Instead of the arrow being in the middle of the button, it is off center by half the width of the screen.
@IBAction func buttonClicked(sender: AnyObject){
var popoverViewController = self.storyboard?.instantiateViewControllerWithIdentifier("ServiceOptions") as! ServiceOptionsPopover
popoverViewController.delegate = self
popoverViewController.modalPresentationStyle = .Popover
popoverViewController.preferredContentSize = CGSizeMake(300, 300)
let popoverPresentationViewController = popoverViewController.popoverPresentationController
popoverPresentationViewController?.permittedArrowDirections = .Up
popoverPresentationViewController?.delegate = self
popoverPresentationViewController?.sourceView = sender as! UIButton
popoverPresentationViewController?.sourceRect = sender.frame
presentViewController(popoverViewController, animated: true, completion: nil)
}
There is an issue in iOS 9. Setting the anchor in a storyboard:
...results in the arrow not being centered on the anchor:
To resolve, add this to
prepareForSegue:sender:
:In my case the problem is different, the popover is shown for a UIBarButtonItem with a custom view. For iOS 11 if you use custom view of UIBarButtonItem, the custom view needs to be auto layout friendly.
With this category you can apply quickly the constraints.
UIView+NavigationBar.h
UIView+NavigationBar.m
Then you can do:
One time you apply the constraints the popover is shown correctly over custom view, e.g., the code for showing a alert as popover is:
Here is the right way:
The problem is the elementary one of confusing frame and bounds:
No! You mean bounds:
The reason is that the
sourceRect
is given in the coordinate space of thesourceView
- that is, if you want it to be the view's rect, it's the bounds of that view.