UIPopOver и изменение ориентации - PullRequest
10 голосов
/ 09 июня 2010

В моем приложении 3 UIPopOvers. Они появляются, когда пользователь нажимает кнопки на панели инструментов. Мне нужно, чтобы всплывающие окна отображались в правильном месте, когда пользователь поворачивает iPad, если поповер уже открыт (например, -willAnimateRotationToInterfaceOrientation:).

Как я могу это сделать?

Заранее спасибо!

Ответы [ 9 ]

10 голосов
/ 07 января 2014

В iOS 7.0 и более поздних версиях это можно сделать, реализовав следующий метод, доступный в UIPopoverControllerDelegate :

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

Для всплывающих окон, представленных с использованием метода presentPopoverFromRect , контроллер всплывающих окон вызывает этот метод при изменении ориентации интерфейса.

6 голосов
/ 27 июня 2010

Единственное решение, которое я нашел до сих пор, это просто закрывать поповер при повороте устройства /

4 голосов
/ 04 июня 2012

Вот фрагмент кода из одного из моих проектов. В основном, если отображается всплывающее окно, вы снова представляете всплывающее окно в методе 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, чтобы проверить его на «non-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];
  }    
}
3 голосов
/ 04 ноября 2010

Если вы просто используете метод presentPopoverFromBarButtonItem для представления вашего поповера, тогда поповер автоматически переместится в правильное положение для новой позиции кнопки при повороте устройства.

2 голосов
/ 27 марта 2013

Я сталкивался с этой же проблемой пару раз.Обычно я просто делаю метод отображения поповера по центру, как это:

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

Это поместит поповер в центр для любой ориентации.

2 голосов
/ 26 апреля 2011

Вы вызываете presentPopoverFromBarButtonItem или FromRect? Вносите ли вы какие-либо изменения в BarButtonItem при повороте?

В документации Apple специально говорится, что вам нужно управлять положением вращения для FromRect или если вы изменяете элемент кнопки панели. Смотри четвертый абзац в http://developer.apple.com/library/ios/#documentation/uikit/reference/UIPopoverController_class/Reference/Reference.html

1 голос
/ 19 октября 2015

В начале изменения ориентации отклоните всплывающее окно, а после того, как изменение ориентации завершено, оно снова и оно меняет свое положение на экране:

- (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];
        }    
    }
0 голосов
/ 08 июня 2018

Вам следует использовать метод UIPopoverPresentationControllerDelegate:

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

и обновить значение прямоугольника.

См. Ответ @Hugo Alonso здесь

0 голосов
/ 01 июня 2017

Выполнение функции поповера:

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