Popover不以按钮为中心

时间:2015-05-05 22:55:08

标签: ios swift uipopovercontroller

我试图将一个弹出按钮放在一个按钮上。我似乎无法弄清楚我可能会出错的地方。它不是按钮中间的箭头,而是偏离屏幕宽度的一半。

 @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)
}

4 个答案:

答案 0 :(得分:53)

问题是混淆框架和边界的基本问题:

popoverPresentationViewController?.sourceView = sender as! UIButton
popoverPresentationViewController?.sourceRect = sender.frame

没有!你的意思是界限:

popoverPresentationViewController?.sourceView = sender as! UIButton
popoverPresentationViewController?.sourceRect = (sender as! UIButton).bounds

原因是sourceRectsourceView的坐标空间中给出 - 也就是说,如果您希望它是视图的直方,那么它就是这种观点的界限。

答案 1 :(得分:44)

iOS 9中存在问题。在故事板中设置锚点:

enter image description here

...导致箭头不在锚点上居中:

enter image description here

要解决此问题,请将其添加到.joinWithSeparator("\n")

prepareForSegue:sender:

enter image description here

答案 2 :(得分:3)

这是正确的方法:

@IBAction func buttonClicked(sender: UIButton){
    var popoverViewController = UIViewController()
    popoverViewController.view.frame = CGRectMake(0,0, 300, 300)
    popoverViewController.view.backgroundColor = UIColor.redColor()
    popoverViewController.modalPresentationStyle = .Popover
    popoverViewController.preferredContentSize   = CGSizeMake(300, 300)

    let popoverPresentationViewController = popoverViewController.popoverPresentationController

    popoverPresentationViewController?.permittedArrowDirections = .Up
    popoverPresentationViewController?.sourceView = sender
    popoverPresentationViewController?.sourceRect = CGRectMake(0, 0, sender.bounds.width,sender.bounds.height) // see this line of code

    presentViewController(popoverViewController, animated: true, completion: nil)
}

答案 3 :(得分:2)

在我的情况下问题不同,弹出窗口显示为具有自定义视图的UIBarButtonItem。对于iOS 11,如果您使用UIBarButtonItem的自定义视图,则自定义视图需要自动布局友好。

使用此类别,您可以快速应用约束。

的UIView + NavigationBar.h

@interface UIView (NavigationBar)

    - (void)applyNavigationBarConstraints:(CGFloat)width height:(CGFloat)height;
    - (void)applyNavigationBarConstraintsWithCurrentSize;

@end

的UIView + NavigationBar.m

#import "UIView+NavigationBar.h"

@implementation UIView (NavigationBar)

- (void)applyNavigationBarConstraints:(CGFloat)width height:(CGFloat)height
{
    if (width == 0 || height == 0) {
        return;
    }

    NSLayoutConstraint *heightConstraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:height];
    NSLayoutConstraint *widthConstraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:width];
    [heightConstraint setActive:TRUE];
    [widthConstraint setActive:TRUE];
}

- (void)applyNavigationBarConstraintsWithCurrentSize {
    [self applyNavigationBarConstraints:self.bounds.size.width height:self.bounds.size.height];
}

@end

然后你可以这样做:

UIButton *buttonMenu = [UIButton buttonWithType:UIButtonTypeCustom];
[buttonMenu setImage:[UIImage imageNamed:@"menu"] forState:UIControlStateNormal];
buttonMenu.frame = CGRectMake(0, 0, 44, 44);
[buttonMenu addTarget:self action:@selector(showMenu:) forControlEvents:UIControlEventTouchUpInside];

//Apply constraints 
[buttonMenu applyNavigationBarConstraintsWithCurrentSize];

UIBarButtonItem *menuBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:buttonMenu];

有一次你应用约束时,弹出窗口会在自定义视图上正确显示,例如,用于显示警告的代码为popover:

UIAlertController *controller = [UIAlertController alertControllerWithTitle:@"Menu" message:@"" preferredStyle:UIAlertControllerStyleActionSheet];
//Add actions ....

UIPopoverPresentationController *popController = [controller popoverPresentationController];
popController.sourceView = buttonMenu;
popController.sourceRect = buttonMenu.bounds;

[self presentViewController:controller animated:YES completion:nil];