2010-06-09 11 views
9

En mi aplicación tengo 3 UIPopOvers. Aparecen cuando el usuario toca botones en la barra de herramientas. Necesito hacer que los popovers aparezcan en el lugar correcto cuando el usuario gira el iPad si el popover ya está abierto (como el -willAnimateRotationToInterfaceOrientation :).UIPopOver y cambio de orientación

¿Cómo puedo hacerlo?

¡Gracias de antemano!

Respuesta

6

La única solución que he encontrado hasta ahora es sólo el cierre de la popover cuando se gira el dispositivo/

+0

Lamentablemente, no puedo hacer nada para desencadenar método willRotate mi punto de vista del controlador, donde estaría normalmente descartar el popover. Me hubiera imaginado que se llamaría sin importar qué. –

+0

También pienso en esta solución que no puedo lograr. :( –

3

Si simplemente utiliza el método presentPopoverFromBarButtonItem para presentar su popover entonces el popover se moverá automáticamente a la posición correcta para la nueva posición del botón cuando se gira el dispositivo.

4

Aquí hay un fragmento de código de uno de mis proyectos. Básicamente, si se muestra el popover, se vuelve a presentar el popover en el método didRotateFromInterfaceOrientation:, que se envía al controlador de vista después de que se haya realizado la rotación de la interfaz del usuario. (Los métodos willRotate... y willAnimateRotation... se llaman antes ha tenido lugar la rotación, por lo que es el lugar equivocado para la llamada presentPopover... método.)

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

En lo anterior, self.myPopoverController es una propiedad de mi controlador de vista, donde Guardo una referencia al popover cuando se crea. Cuando descarto y desecho el popover en circunstancias normales, me ocupo de establecer esta propiedad en nil, por lo que puedo verificar si no está nil 'ness para decidir si se muestra o no el popover.

Tenga en cuenta, sin embargo, que no necesita cerrar el popover antes de que se produzca la rotación. Solo presenta el mismo popover de nuevo. (Aquí es donde mantener una referencia a la popover viene muy bien.)

En su caso, en el que el popover emana de un botón de la barra, se usaría algo como lo siguiente en su lugar:

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

I' Me he topado con este mismo problema un par de veces. Me suelen hacer simplemente un método para mostrar la popover centrado en este aspecto:

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

Luego, el didRotate yo:

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

Esto pondrá el popover en el centro de cualquier orientación.

10

En iOS 7.0 y después, se puede hacer mediante la implementación siguiente método disponible en UIPopoverControllerDelegate:

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

Para popovers que se presentaron usando el métodopresentPopoverFromRect, el controlador popover llama a este método cuando los cambios de orientación de la interfaz.

+0

Esta es, de lejos, la mejor manera de hacer esto después de iOS7. – logancautrell

+0

'CGRect frame = self.myView.frame; * rect = frame;' – logancautrell

+0

Esto incluso solucionó otro error con 'drawRect' que no se llamaba nuevamente en un ver en mi popover. ¡Gran respuesta, debería ser la aceptada! –

1

Al comienzo del cambio de orientación descartar el popover, y después se completa de nuevo el cambio de orientación y cambia presente su posición en la pantalla:

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

Agregue más detalles, en lugar de simplemente pegar el código. – kinshuk4

0

Realización función popover:

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

Descartando popover presentado en la orientación cambiante:

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

Presentar popover nuevo:

func popoverPresentationController(popoverPresentationController: UIPopoverPresentationController, willRepositionPopoverToRect rect: UnsafeMutablePointer<CGRect>, inView view: AutoreleasingUnsafeMutablePointer<UIView?>) { 
    self.presentPopover() 
} 
Cuestiones relacionadas