【问题标题】:UIPopOver and orientation changeUIPopOver 和方向改变
【发布时间】:2010-06-09 17:58:37
【问题描述】:

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

我该怎么做?

提前致谢!

【问题讨论】:

    标签: ipad uipopovercontroller


    【解决方案1】:

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

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

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

    【讨论】:

    • 这是 iOS7 之后最好的方法。
    • CGRect frame = self.myView.frame; *rect = frame;
    • 这甚至修复了另一个错误,drawRect 在我的弹出窗口中的视图上没有被再次调用。很好的答案,应该被接受!!!
    • willRepositionPopoverToRect 中调用我的呈现弹出框功能对我有用。谢谢!
    【解决方案2】:

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

    【讨论】:

    • 可悲的是,我无法触发视图控制器的 willRotate 方法,我通常会在该方法中关闭弹出框。我本以为无论如何都会被调用。
    • 我也想这个解决方案我做不到。 :(
    • 这在某些情况下会起作用,但对我来说这不是一个可行的解决方案,因为关闭和呈现视图会从内存中释放视图和 viewController。这使得无法在方向改变期间保持状态。例如,假设用户在弹出窗口中选择了一些东西,然后旋转屏幕。他们将不得不重新做他们在弹出窗口中所做的任何工作。
    【解决方案3】:

    这是我的一个项目的代码片段。基本上,如果弹出框正在显示,您将在方法didRotateFromInterfaceOrientation: 中再次显示弹出框,该方法在用户界面旋转发生后 发送到视图控制器。 (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];
      }    
    }
    

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        【解决方案5】:

        您是在调用 presentPopoverFromBarButtonItem 还是 FromRect?您是否对旋转时的 BarButtonItem 进行了任何更改?

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

        【讨论】:

          【解决方案6】:

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

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

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

          【讨论】:

            【解决方案7】:

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

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

            【讨论】:

            • 请添加更多详细信息,而不仅仅是粘贴代码。
            【解决方案8】:

            执行弹出功能:

            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()
            }
            

            【讨论】:

              【解决方案9】:

              你应该使用 UIPopoverPresentationControllerDelegate 方法:

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

              并更新矩形值。

              查看@Hugo Alonso 的回答here

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2011-05-05
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多