UIPopover presentFromBarButton偏离中心

时间:2014-06-30 20:12:23

标签: ios uibarbuttonitem uipopovercontroller

我在一个项目中注意到,由于某种原因,右侧栏按钮项目上的弹出窗口的位置似乎偏向右侧。我尝试使用UIButton作为自定义视图,然后从该按钮显示弹出窗口,但是popover似乎忽略了showFromRect,如果我实际上提供了'居中'值。

Off-center popover

这背后的代码非常简单:

- (void)viewDidLoad {
    [super viewDidLoad];

     UIBarButtonItem *button = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"share"] style:UIBarButtonItemStylePlain target:self action:@selector(shareTap:)];

     self.navigationItem.rightBarButtonItem = button;
}

- (void)shareTap:(UIBarButtonItem *)button {
    self.popover = [[UIPopoverController alloc] initWithContentViewController:[[UIViewController alloc] init]];

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

现在,如果我切换到使用内部按钮,如上所述,我看到类似的行为(注意颜色变化,因此图像显示)。

using internal button

此代码仍然相当简单:

- (void)viewDidLoad {
    [super viewDidLoad];

    UIButton *innerButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 22, 22)];
    [innerButton setImage:[UIImage imageNamed:@"share"] forState:UIControlStateNormal];
    [innerButton addTarget:self action:@selector(shareTap:) forControlEvents:UIControlEventTouchUpInside];

    self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:innerButton];;
}

- (void)shareTap:(UIButton *)button {
    self.popover = [[UIPopoverController alloc] initWithContentViewController:[[UIViewController alloc] init]];

//    CGRect bottomCenter = CGRectMake(button.frame.size.width / 2, button.frame.size.height, 1, 1);
    CGRect bottomCenter = CGRectMake(2, button.frame.size.height, 1, 1);

    [self.popover presentPopoverFromRect:bottomCenter inView:button permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
}

请注意,我没有使用实际的中心,而是使用了任意值,2。如果我使用1或0,则弹出框将变为左对齐。任何大于1的东西都会再次右对齐。

left-aligned

我搜索了一下寻找类似的问题,但我似乎无法找到有同样问题的人。任何关于导致这种情况或如何避免它的想法将不胜感激。我唯一能够猜到的是,由于它靠近边缘,Apple做了一些定位巫术,迫使它成为他们想要的地方。问题是,右上角按钮看起来像是一个非常标准的下拉位置。

编辑:我已经确认,长按“"新消息”"会发生同样的行为。本机邮件应用程序中的图标。

编辑2:我能够向Apple确认这是一个问题。在最近的一个版本中(我不记得哪个版本,我认为其中一个版本),他们制作了它,因此你可以手动设置它。默认行为仍然是错误的我相信(我还没试过这一段时间),但如果您愿意,可以使用CGRect偏移方法使其正常工作。

2 个答案:

答案 0 :(得分:1)

以下是执行此操作的一种方法:使用带有自定义视图的UIBarButtonSystemItem,而不是使用UIBarButtonItem。只需将UIButton拖到UINavigationBar即可获得带有嵌入式UIBarButtonItem的{​​{1}},其显示为UIButton的自定义视图。

UIBarButtonItem

答案 1 :(得分:0)

您必须指定需要显示弹出窗口的小节按钮的框架。

以下代码将UIAlertController显示为条形按钮的弹出窗口。

    @IBOutlet weak var playerRightBarButton: UIBarButtonItem!

    extension UIBarButtonItem {
       var frame: CGRect? {
        guard let view = self.value(forKey: "view") as? UIView else {
          return nil
      }
      return view.frame
    }
  }

    let alert = UIAlertController(title: "", message: "Sample PopOver", 
    preferredStyle: .actionSheet)
    if alert.responds(to: #selector(getter: popoverPresentationController)) {
            alert.popoverPresentationController?.sourceView = self.view
            alert.popoverPresentationController?.barButtonItem = playerRightBarButton
            alert.popoverPresentationController?.permittedArrowDirections = .up
            if let frame = playerRightBarButton.frame {
                alert.popoverPresentationController?.sourceRect = frame
            }
        }
        self.present(alert, animated: true, completion: nil)