【问题标题】:UIPopoverController Appears in Wrong SpotUIPopoverController 出现在错误的位置
【发布时间】:2011-07-08 19:59:34
【问题描述】:

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

我正在尝试从 UIInputAccessoryView 上的按钮呈现弹出框。我想从中显示弹出框的 UIBarButtonItem 有一个自定义视图,因此我可以使用图像。我这样创建按钮:

 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];

但我得到的是这样的:

弹出框看起来不错,但它应该出现在第一个按钮上时却出现在第二个按钮上。

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

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

最后,我要指出的是,我在程序的其他地方还有其他条形按钮项目,这些项目不在 UIInputAccessoryViews 中,它们可以正常出现并且没有问题。它似乎只发生在输入附件视图中。

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

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

非常感谢。

【问题讨论】:

  • 你试过[UIPopoverController presentPopoverFromBarButtonItem:(UIBarButtonItem *)item permittedArrowDirections:(UIPopoverArrowDirection)arrowDirections animated:(BOOL)animated]吗?如果您有条形按钮项,则最好这样做。
  • @bshirley - 是的,我确实尝试过。我在子类 uibarbuttonitem 上面引用的问题是为了更轻松地创建带有图像而不是文本的 barbuttonitem。当我这样做并使用... popoverfrombarbuttonitem... 结果是上面的第二张图片,其中弹出框出现在正确的位置但旋转不正确。

标签: ios cocoa-touch uipopovercontroller uibarbuttonitem uiinterfaceorientation


【解决方案1】:

所以我得到了它与以下 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];

【讨论】:

  • 您应该使用bounds 属性而不是frameconvertRect:toView: 将接收方坐标系中的矩形转换为toView: 中传递的视图。视图的frame 在其父视图的坐标系中,而bounds 在该视图的坐标系中。
  • 或者你可以使用 [self.popoverController presentPopoverFromRect:[sender frame] inView:self.view allowedArrowDirections:UIPopoverArrowDirectionDown animated:YES];会没事的
【解决方案2】:

我遇到了完全相同的问题,即弹出框指向 iOS 7 中的不同位置,感谢Chris' answer,我终于能够看到 iOS 6 和 iOS 7 之间的一致性。我不得不对通过将 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];

【讨论】:

  • 非常简单的解决方案。在 XCode 5.0 中运行良好!
  • 你有什么理由不这样称呼这条线吗? CGRect tRect=[sender convertRect:sender.bounds toView:self.view];
  • @EvanR 好点子,这里没有理由将它从 id 转换为 UIButton,因为无论如何我都可以向它发送任何消息
【解决方案3】:

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

【讨论】:

  • 是的。正如我在我的问题和上面的评论中解释的那样,我确实尝试过,结果是一个正确定位但不正确旋转的弹出框。不过,谢谢。
  • 嗯...您是否允许任何箭头方向?视图可能已被旋转以适应指定的箭头方向?否则,这真的很奇怪。
【解决方案4】:

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

【讨论】:

    【解决方案5】:

    试试这个:

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

    【讨论】:

      【解决方案6】:

      你可以抵消那个点:

      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!
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-12-08
        • 1970-01-01
        • 2014-09-05
        相关资源
        最近更新 更多