UIPopoverController出现在错误的位置

Chr*_*ris 7 cocoa-touch uibarbuttonitem uipopovercontroller uiinterfaceorientation ios

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

我正在尝试从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];
Run Code Online (Sandbox Code Playgroud)

当需要显示popover时,我这样做:

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];
Run Code Online (Sandbox Code Playgroud)

但我得到的是:

在此输入图像描述

弹出窗口看起来很好,但是它应该出现在第一个按钮上时出现在第二个按钮上.

然后我发现了这个问题:UIBarButtonItem带有自定义图像而且没有边框,我想,"啊,如果我从barbuttonitem呈现popover而不是这样做,它可能会更好.代码子类UIBarButtonItem为了有一个带图像的按钮,而不是文本,并在调用动作时正确表示barbuttonitem.这允许我使用... presentPopoverFromBarButtonItem ...

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

弹出错误的方向

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

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

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

非常感谢你.

Chr*_*ris 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];
Run Code Online (Sandbox Code Playgroud)

  • 你应该使用`bounds`属性而不是`frame`.`convertRect:toView:`将rect从接收者的坐标系转换为`toView:`中传递的视图.视图的"框架"在其超视图的坐标系中,而"边界"在该视图的坐标系中. (3认同)

Kor*_*ton 5

我有完全相同的问题,popover指向iOS 7中的另一个地方,并且由于Chris的回答,我终于能够看到iOS 6和iOS 7之间的一致性.我不得不通过替换对代码进行1次微调整framebounds将它定位在那里我希望它是.

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];
Run Code Online (Sandbox Code Playgroud)