iOS9 popover always points to top-left corner of a

2019-03-17 05:14发布

I'm using a storyboard segue that presents a view controller as popover. The seque has a custom UIView as its anchor. On pre-iOS9 the popover would correctly point to the centre-bottom of the custom UIView (presented below the UIView). On iOS9 it points to the top-left corner of the UIView.

I did try to trace all selector calls to the custom UIView to find out if there is anything I may need to implement in my custom UIView to provide the 'hotspot' for the popover but couldn't find anything

Any ideas..? Thanks

Thanks to @Igor Camilo his reply - in case it's useful to some, this is how I fixed this in my code:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {

     UIPopoverPresentationController* possiblePopOver = segue.destinationViewController.popoverPresentationController;
     if (possiblePopOver != nil) {
         //
         // iOS9 -- ensure correct sourceRect
         //
         possiblePopOver.sourceRect = possiblePopOver.sourceView.bounds;
     }
    ...
 }

Example: 'Short' button triggers a popover, the popover points to the top-left corner of 'Sort' control

Resulting popover

Segue settings

标签: ios uiview uikit
9条回答
混吃等死
2楼-- · 2019-03-17 05:52

Here's an example of Igor Camilo's snippet in Objective-C.

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    // If the sender is a UIView, we might have to correct the sourceRect of
    // a potential popover being presented due to an iOS 9 bug. See:
    // https://openradar.appspot.com/22095792 and http://stackoverflow.com/a/32698841/368674
    if ([sender isKindOfClass:UIView.class]) {
        // Fetch the destination view controller
        UIViewController *destinationViewController = [segue destinationViewController];

        // If there is indeed a UIPopoverPresentationController involved
        if ([destinationViewController respondsToSelector:@selector(popoverPresentationController)]) {
            // Fetch the popover presentation controller
            UIPopoverPresentationController *popoverPresentationController =
            destinationViewController.popoverPresentationController;

            // Set the correct sourceRect given the sender's bounds
            popoverPresentationController.sourceRect = ((UIView *)sender).bounds;
        }
    }
}
查看更多
The star\"
3楼-- · 2019-03-17 05:56

If you reference your popover UIViewController in your main UIViewController you can adjust the sourceRect property to offset the popover. For example, given popover popoverVC you can do something like so:

float xOffset = 10.0;
float yOffset = 5.0;
popoverVC.popoverPresentationController.sourceRect = CGMakeRect(xOffset, yOffset, 0.0, 0.0);
查看更多
走好不送
4楼-- · 2019-03-17 06:05

Here's my solution, inside prepareForSegue:

segue.destinationViewController.popoverPresentationController?.sourceRect = CGRectMake(anchorView.frame.size.width/2, anchorView.frame.size.height, 0, 0)

This will move the pointer to the bottom middle of the anchor view

查看更多
Evening l夕情丶
5楼-- · 2019-03-17 06:06

I had the exact same problem. I just resolved it by setting sourceRect in prepareForSegue:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    switch segue.identifier {
    case "Popover Identifier"?:
        if #available(iOS 9.0, *) {
            segue.destinationViewController?.popoverPresentationController?.sourceRect = anchorView.bounds
        }
    default:
        break
    }
}
查看更多
可以哭但决不认输i
6楼-- · 2019-03-17 06:06

I also encountered this problem but now it works when I added this to my PrepareForSegue function. Given that my Segue ID contains string Popover

if ([[segue identifier] containsString:@"Popover"]) {
    [segue destinationViewController].popoverPresentationController.sourceRect = self.navigationItem.titleView.bounds;
}
查看更多
可以哭但决不认输i
7楼-- · 2019-03-17 06:06

Try to set width and height anchor of your source rect (UIView or UIBarButtonItem ) and set it to active .Set it when you are initialising your UIView or UIBarButtonItem.

UIBarButtonItem

 [[youruibarbuttonitem.customView.widthAnchor constraintEqualToConstant:youruibarbuttonitem.customView.bounds.size.width] setActive:YES];
 [[youruibarbuttonitem.customView.heightAnchor constraintEqualToConstant:youruibarbuttonitem.customView.bounds.size.height] setActive:YES];

UIView

[[uiview.widthAnchor constraintEqualToConstant:uiview.bounds.size.width] setActive:YES];
 [[uiview.heightAnchor constraintEqualToConstant:uiview.bounds.size.height] setActive:YES];
查看更多
登录 后发表回答