10

在我的应用程序中,我有 3 个 UIPopOver。当用户点击工具栏中的按钮时,它们就会出现。如果弹出框已经打开(例如 -willAnimateRotationToInterfaceOrientation :),我需要在用户旋转 iPad 时使弹出框出现在正确的位置。

我该怎么做?

提前致谢!

4

9 回答 9

11

在 iOS 7.0 及更高版本中,可以通过实现UIPopoverControllerDelegate中可用的以下方法来完成:

(void)popoverController:(UIPopoverController *)popoverController willRepositionPopoverToRect:(inout CGRect *)rect inView:(inout UIView **)view

对于使用presentPopoverFromRect方法呈现的弹出框,弹出框控制器会在界面方向更改时调用此方法。

于 2014-01-07T11:07:53.380 回答
6

到目前为止,我发现的唯一解决方案就是在设备旋转时关闭弹出框/

于 2010-06-27T12:32:00.397 回答
4

这是我的一个项目的代码片段。基本上,如果弹出框正在显示,则在方法中再次显示弹出框,在用户界面旋转发生后将didRotateFromInterfaceOrientation:其发送到视图控制器。(and方法是在旋转发生之前调用的,所以它是方法调用的错误位置。)willRotate...willAnimateRotation...presentPopover...

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
  // if the popover is showing, adjust its position after the re-orientation by presenting it again:
  if (self.myPopoverController != nil)  // if the popover is showing (replace with your own test if you wish)
  {
    [self.myPopoverController presentPopoverFromRect:attachmentRect
                                              inView:myView
                            permittedArrowDirections:UIPopoverArrowDirectionUp
                                            animated:YES];
  }    
}

在上面,self.myPopoverController是我的视图控制器的一个属性,我在它创建时存储对弹出框的引用。当我在正常情况下关闭并丢弃弹出框时,我会注意将此属性设置为nil,因此我可以检查它是否“非nil”来决定是否显示弹出框。

但是请注意,您不需要在旋转发生之前关闭弹出框。只需再次呈现相同的弹出框。(这是保留对弹出框的引用的地方。)

在您的情况下,弹出框从工具栏按钮发出,您可以使用以下内容:

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
  // if the popover is showing, adjust its position after the re-orientation by presenting it again:
  if (self.myPopoverController != nil)  // if the popover is showing (replace with your own test if you wish)
  {
    [self.myPopoverController presentPopoverFromBarButtonItem:barButtonItem
                                     permittedArrowDirections:UIPopoverArrowDirectionAny
                                                     animated:YES];
  }    
}
于 2012-06-04T15:02:02.653 回答
3

如果您只是使用 presentPopoverFromBarButtonItem 方法来展示您的弹出框,那么当设备旋转时,弹出框将自动移动到新按钮位置的正确位置。

于 2010-11-04T11:20:07.397 回答
2

你打电话给 presentPopoverFromBarButtonItem 还是 FromRect?您是否对旋转时的 BarButtonItem 进行了任何更改?

Apple 的文档特别指出您需要管理 FromRect 的旋转位置,或者如果您修改栏按钮项目。请参阅http://developer.apple.com/library/ios/#documentation/uikit/reference/UIPopoverController_class/Reference/Reference.html中的第四段

于 2011-04-26T14:31:05.583 回答
2

我遇到过同样的问题几次。我通常只是制作一种方法来显示居中的弹出框,如下所示:

- (void) showPopoverForSize:(CGSize) size center:(CGPoint) center {
   CGFloat width = size.width;
    CGFloat height = size.height;
    CGFloat x = center.x - width / 2;
    CGFloat y = center.y - height / 2;
    CGRect frame = CGRectMake(x, y, width, height);
    popover.popoverContentSize = frame.size;

    [popover presentPopoverFromRect:frame inView:self.view permittedArrowDirections:0 animated:YES];
}

然后在 didRotate 我做:

- (void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
    [super didRotateFromInterfaceOrientation:fromInterfaceOrientation];
    if (popover.isPopoverVisible)
        [self showPopoverForSize:popover.popoverContentSize center:self.view.center];
}

这会将弹出框置于任何方向的中心。

于 2013-03-27T00:15:24.707 回答
1

在开始改变方向时关闭弹出框,在改变方向后再次完成它并改变它在屏幕上的位置:

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
            [_popover dismissPopoverAnimated:YES];
        }
    }

    - (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
    {
        if (_popover) {
            [_popover presentPopoverFromRect:frameRect
                                                      inView:self.view
                                    permittedArrowDirections:UIPopoverArrowDirectionUp
                                                    animated:YES];
        }    
    }
于 2015-10-19T11:21:31.380 回答
0

执行弹出功能:

func presentPopover() {
    self.popoverFlag = true
    //Presenting PopOver code goes here
    // ...
}

在改变方向时关闭呈现的弹出框:

override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {

        if self.isKindOfClass(ViewController) && self.popoverFlag{
            guard self.presentedViewController != nil else { return }
            dispatch_async(dispatch_get_main_queue()) {
                self.presentedViewController!.dismissViewControllerAnimated(true, completion: nil)
            }
        }
    }

再次呈现弹出框:

func popoverPresentationController(popoverPresentationController: UIPopoverPresentationController, willRepositionPopoverToRect rect: UnsafeMutablePointer<CGRect>, inView view: AutoreleasingUnsafeMutablePointer<UIView?>) {
    self.presentPopover()
}
于 2017-06-01T07:37:20.220 回答
0

您应该使用 UIPopoverPresentationControllerDelegate 方法:

func popoverPresentationController(_ popoverPresentationController: UIPopoverPresentationController, willRepositionPopoverTo rect: UnsafeMutablePointer<CGRect>, in view: AutoreleasingUnsafeMutablePointer<UIView>)

并更新矩形值。

在此处查看@Hugo Alonso 的答案

于 2018-06-08T09:40:33.853 回答