UIPopoverController出现在错误的位置

时间:2011-07-08 19:59:35

标签: ios cocoa-touch uipopovercontroller uibarbuttonitem uiinterfaceorientation

所以我花了一些时间寻找答案,但到目前为止还没有找到任何答案。

我正在尝试从UIInputAccessoryView上的按钮呈现弹出窗口。 UIBarButtonItem我想显示popover来自定制视图,所以我可以使用图像。我创建了这样的按钮:

 buttonImage=[UIImage imageNamed:@"tags.png"];
 aButton=[UIButton buttonWithType:UIButtonTypeCustom];
 [aButton setImage:buttonImage forState:UIControlStateNormal];
 aButton.frame=CGRectMake(0.0, 0.0, buttonImage.size.width, buttonImage.size.height);
 UIBarButtonItem* compButton2=[[UIBarButtonItem alloc]initWithCustomView:aButton];
 [aButton addTarget:self action:@selector(tagIt:) forControlEvents:UIControlEventTouchUpInside];

当需要显示弹出框时,我这样做:

CGRect tRect=[((UIButton*)sender) convertRect:((UIButton*)sender).frame toView:self.notePlainText];
NSLog(@"TagIt tRect: %f %f %f %f", tRect.origin.x, tRect.origin.y, tRect.size.width, tRect.size.height);
[self.popoverController presentPopoverFromRect:tRect inView:self.notePlainText permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];

但我得到的是:

enter image description here

popover看起来不错,但是当它出现在第一个按钮上时,它会显示在第二个按钮上。

然后我发现了这个问题:UIBarButtonItem with custom image and no border并且我想,“啊,如果我从barbuttonitem呈现popover而不是这样做,它可能会更好。代码子类UIBarButtonItem以便有一个带图像的按钮,而不是文本,并在调用动作时正确表示barbuttonitem。这允许我使用... presentPopoverFromBarButtonItem ...

所以我在上述问题的第二个答案中尝试了代码,并得到了更好的结果。弹出按钮指向我想要的按钮,但如果设备的方向不是纵向,底部有按钮,则弹出框的显示方向错误:

Popover with wrong orientation

最后,我将指出我在程序中的其他地方有其他条形按钮项目,这些项目不在UIInputAccessoryViews中,而且没有问题。它似乎只是从输入附件视图中发生。

这就是:隐藏和显示键盘似乎使这项工作更好一点。查看按钮的框架(CGRect)数据,它不会在旋转之间发生变化,除非它被隐藏并带回。这是一个错误吗?

所以......我的问题是:从ui附件视图中嵌入的条形按钮项目呈现弹出窗口的首选最佳实践方法是什么?

非常感谢。

6 个答案:

答案 0 :(得分:8)

所以我用下面的kludgy代码来处理这个问题,虽然如果有人能告诉我为什么要这样做(或者为什么我应该这样做),我会非常感激。

CGRect r=((UIButton*)sender).frame;
CGRect tRect=[((UIButton*)sender) convertRect:((UIButton*)sender).frame toView:self.view];
tRect.origin.x=r.origin.x;

[self.popoverController presentPopoverFromRect:tRect inView:self.view permittedArrowDirections:UIPopoverArrowDirectionDown animated:YES];

答案 1 :(得分:5)

我遇到了完全相同的问题,其中popover指向iOS 7中的不同位置并感谢Chris' answer我终于能够看到iOS 6和iOS 7之间的一致性。我不得不进行1次小调整通过将frame替换为bounds来使代码位于我预期的位置。

CGRect r = [sender frame];
CGRect tRect = [sender convertRect:sender.bounds toView:self.view];
tRect.origin.x=r.origin.x;

[self.popoverController presentPopoverFromRect:tRect inView:self.view permittedArrowDirections:UIPopoverArrowDirectionDown animated:NO];

答案 2 :(得分:1)

使用presentPopoverFromBarButtonItem:permittedArrowDirections:animated。要做到这一点,请确保您有一个对条形按钮的引用(通过将其存储在视图控制器上的属性中,或使用IBOutlet),然后在要显示的弹出窗口上调用该方法。

答案 3 :(得分:1)

我在this answer中使用了相同的解决方法;这似乎是iOS 4.3(可能是4.x)的问题。它似乎在iOS 5中得到修复。

答案 4 :(得分:0)

试试这个:

[self.popoverController presentPopoverFromRect:[sender bounds]
                    inView:sender
  permittedArrowDirections:UIPopoverArrowDirectionAny 
                  animated:YES];

答案 5 :(得分:0)

你可以忽略这一点:

if segue.identifier == "layersPopover"
{
    let vc = segue.destinationViewController
    let controller = vc.popoverPresentationController

    if controller != nil
    {
        controller?.delegate = self

        var rect = controller?.sourceRect
        rect?.offsetInPlace(dx: 19, dy: 0)
        controller?.sourceRect = rect!
    }
}