【问题标题】:IOS8 how to move an active popoverIOS8如何移动一个活动的popover
【发布时间】:2014-11-29 05:14:04
【问题描述】:

我已经为 iOS7 开发了一个应用程序,现在正在尝试为 iOS8 更新它。 我遇到的问题如下:

应用程序的屏幕方向可以旋转,并且在某些情况下,一些按钮会大幅移动。我有一些指向这些按钮的弹出框,所以如果屏幕旋转时弹出框打开,按钮移动,我也需要弹出框。

在 iOS7 中,我通过以下方式做到了这一点: 当屏幕旋转时,我更新了约束

- (void) updateViewConstraints 
{
    if (UIInterfaceOrientationIsLandscape(self.interfaceOrientation))
    {
        self.Button.constant = (CGFloat)10;
    }
    else
    {
        self.Button.constant = (CGFloat)5;
    }
    [super updateViewConstraints];
} 

我也移动了弹出框

- (void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation{

    if(TempDisplayPopoverController == examplePopoverController)
    {
        [examplePopoverController presentPopoverFromRect:[self ExamplePopoverPosition] inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
    }
}

我最初加载弹出框

- (void) LoadPopover{
    examplePopover = [[examplep alloc] initWithNibName:@"exampleP" bundle:nil];
    [examplePopover setDelegate:self];
    examplePopoverController = [[UIPopoverController alloc] initWithContentViewController: examplePopover];
    [examplePopoverController setDelegate:self];

    examplePopoverController.popoverContentSize = examplePopover.view.frame.size;

    TempDisplayPopoverController = examplePopoverController;


    if ([examplePopoverController isPopoverVisible])
    {
        [examplePopoverController dismissPopoverAnimated:YES];
    }
    else
    {
        [examplePopoverController presentPopoverFromRect:[self ExamplePopoverPosition] inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
    }
}

[self ExamplePopoverPosition] 只是返回按钮位置。

这一切都很好,我很高兴,iPad 很高兴并且一切正常。

现在由于 iOS8,我必须更改一些位。

self.interfaceOrientation 已折旧

[examplePopoverController presentPopoverFromRect:[self ExamplePopoverPosition] inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];

didRotateFromInterfaceOrientation 中抛出错误

"Application tried to represent an active popover presentation: <UIPopoverPresentationController: 0x7bf59280>"

我已经设法通过

纠正self.interfaceOrientation
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
    [self SetUpScreen:toInterfaceOrientation];
}

- (void) SetUpScreen:(UIInterfaceOrientation)toInterfaceOrientation{
    if (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft ||
        toInterfaceOrientation == UIInterfaceOrientationLandscapeRight)
    {
        self.Button.constant = (CGFloat)10;
    }
    else
    {
        self.Button.constant = (CGFloat)5;
    }
    [super updateViewConstraints];
}

但不知道如何解决弹出框问题。我试过了

popoverController: willRepositionPopoverToRect: inView:

但似乎无法让它工作。

谁能给点建议

谢谢

【问题讨论】:

  • 这里有同样的问题。我们必须问苹果...
  • 你好,我还没有解决这个问题
  • 这有什么更新吗?我有同样的问题
  • 不幸的是还没有稳定的东西
  • 以 UIView 的形式访问 xib 文件的内容,并在 updateViewConstraints stackoverflow.com/a/7814977/1546710 中更新框架

标签: objective-c screen-orientation uipopover


【解决方案1】:

在 iOS 8 中,您可以使用 -viewWillTransitionToSize:withTransitionCoordinator: 来处理屏幕尺寸(和方向)的变化:

- (void)viewWillTransitionToSize:(CGSize)size
       withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator 
{
    [_popover dismissPopoverAnimated:NO];
    [coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) {
         // Update your layout for the new size, if necessary.  
         // Compare size.width and size.height to see if you're in landscape or portrait.
    } completion:^(id<UIViewControllerTransitionCoordinatorContext> context) {
        [_popover presentPopoverFromRect:[self popoverFrame] 
                                  inView:self.view
                permittedArrowDirections:UIPopoverArrowDirectionAny 
                                animated:NO];
    }];
}

实现此方法后,在 iOS 8 上运行时不会调用 willAnimateRotationToInterfaceOrientation: 等已弃用的旋转方法。

【讨论】:

    【解决方案2】:

    使用popoverController:willRepositionPopoverToRect:inView:时,重新赋值给rect参数时,尝试使用:

    *rect = myNewRect;
    

    而不是:

    rect = &presentingRect;
    

    另外,请确保您已正确分配弹出框控制器的委托。

    【讨论】:

      【解决方案3】:

      首先,您无需在轮换时关闭并呈现弹出框。 UIPopoverPresentationController 会为你做这些。一旦在创建弹出框时设置了 sourceView/sourceRect,您甚至不需要更新它们。

      现在,animate(alongsideTransition: ((UIViewControllerTransitionCoordinatorContext) -&gt; Void)?, completion: ((UIViewControllerTransitionCoordinatorContext) -&gt; Void)? = nil) 的诀窍是您应该在 alongsideTransition 闭包中更新约束,而不是在 completion 中。这样可以确保在旋转结束时恢复弹出框时 UIPopoverPresentationController 具有更新的 sourceRect。

      看起来有悖常理的是,在 alongsideTransition 闭包中,您已经有了新的布局,您可以从中导出约束计算。

      以下是 Swift 中的示例:

      override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
          super.viewWillTransition(to: size, with: coordinator)
          coordinator.animate(alongsideTransition: { _ in
              if self.popover != nil {
                  // optionally scroll to popover source rect, if inside scroll view
                  let rect = ...
                  self.scrollView.scrollRectToVisible(rect, animated: false)
      
                  // update source rect constraints
                  myConstraint.constant = ...
                  myConstrainedView.setNeedsLayout()
                  myConstrainedView.layoutIfNeeded()
              }
          }, completion: nil)
      }
      

      【讨论】:

        【解决方案4】:

        非常有趣 - 我无需手动更新位置就可以使用它。我不知道为什么这行得通。

        let buttonContainer = UIView(frame: CGRectMake(0, 0, 44, 44))
        let button = UIButton(frame: CGRectMake(0, 0, 44, 44))
        buttonContainer.addSubview(button)
        view.addSubview(buttonContainer)
        
        popover!.presentPopoverFromRect(button, inView: button.superview!, permittedArrowDirections: .Any, animated: true)
        

        将弹出框显示的按钮放在“容器视图”中。然后弹出框会自动在方向改变时调整位置。

        【讨论】:

        • 请在投反对票之前尝试此解决方案。我知道这听起来很疯狂,但它对我有用。
        猜你喜欢
        • 1970-01-01
        • 2015-05-11
        • 1970-01-01
        • 2015-09-15
        • 2019-08-24
        • 2015-04-05
        • 1970-01-01
        • 2013-07-05
        • 1970-01-01
        相关资源
        最近更新 更多