2011-12-22 21 views
8

Actualmente tengo una aplicación para iPad con una UIToolbar que contiene dos UIBarButtonItems, cada uno de los cuales está conectado a un popover segue.UIBarButtonItem + popover segue crea múltiples popovers

Cuando el usuario toca cualquiera de los UIBarButtonItems, se crea el popover en lugar de alternar. Esto crea múltiples popovers superpuestos. He sido capaz de cerrar la popover previamente creada usando el siguiente código

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 
    // First close the preferences popover if it's open per Apple guidelines 
    if ([self.popoverA.popoverController isPopoverVisible]) { 
     [self.popoverA.popoverController dismissPopoverAnimated:YES]; 
    } 

    if ([self.popoverB.popoverController isPopoverVisible]) { 
     [self.popoverB.popoverController dismissPopoverAnimated:YES]; 
    } 
    ... code to manage segues ... 
} 

También tengo UIButtons que crean segues popover que se comportan normalmente. Debido a este comportamiento de los popovers asociados con UIBarButtonItems, mi aplicación está siendo rechazada. ¿Alguien tiene alguna sugerencia o muestras de código de una UIToolbar con varios UIBarButtonItems que funcionan correctamente? Los popovers se descartan cuando el usuario toca fuera de la ventana,

+0

Solo para aclarar mi problema. El comportamiento esperado es que cada vez que se toca el botón (UIBarButtonItem), el popover debe activarse o cerrarse en lugar de abrirse siempre. La segue, sin embargo, parece crear siempre otro popover, en lugar de descartar uno visible existente. Cuando se vincula a un UIButton, los popovers se cambian apropiadamente. –

Respuesta

8

En el momento en que recibe el mensaje en -prepareForSegue:sender:, es demasiado tarde para cancelar un cambio.

Para hacer esto de manera eficiente, debe crear segues para los popovers desde el controlador de vista en lugar de los botones de barra para que aún puedan ejecutarse programáticamente. Ahora conecte el UIBarButtonItem s a algunos métodos que condicionalmente presentarán o descartarán el popover.

- (IBAction)showPopoverA 
{ 
    if (self.popoverA.popoverController.popoverVisible) 
     [self.popoverA.popoverController dismissPopoverAnimated:YES]; 

    [self performSegueWithIdentifier:@"ShowPopoverA"]; 
} 
+0

Gracias por el consejo, lo intentaré! –

+1

Después de intentar esa sugerencia, aparece el siguiente error: ** Aplicación de terminación debido a excepción no detectada 'NSInternalInconsistencyException', razón: 'UIStoryboardPopoverSegue debe presentarse desde un elemento de botón de barra o una vista. ** –

+0

'- (IBAction) showPopoverA: (id) remitente { if ([self.popoverA.popoverController isPopoverVisible]) {[self.popoverA.popoverController dismissPopoverAnimated: YES]; } [self performSegueWithIdentifier: @ "showPopoverASegue" remitente: remitente]; } ' –

16

Ésta es la forma correcta de hacer lo que tiene que hacer:

- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender { 
    if ([identifier isEqualToString:@"SurveyListPopover"]) { 
     if (self.surveyListPopover == nil) { 
      return YES; 
     } 
     return NO; 
    } 
    return YES; 
} 

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 
    if ([segue.identifier isEqualToString:@"SurveyListPopover"]) { 
     // Assign popover instance so we can dismiss it later 
     self.surveyListPopover = [(UIStoryboardPopoverSegue *)segue popoverController]; 
    } 
} 

Esto asegura que la segue será cancelado si ya se ha visualizado una instancia de la popover. Solo necesita asegurarse de que su objeto popover tenga un identificador en el guión gráfico.

+0

Si se dirige a más de 6.0, este es el mejor enfoque hasta ahora. –

+0

¿es solo yo o en ios 5 shouldPerformSegueWithIdentifier no recibe ninguna llamada? –

+0

https://developer.apple.com/library/ios/documentation/uikit/reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instm/UIViewController/shouldPerformSegueWithIdentifier:sender: Parece que se introdujo en iOS 6.0 y arriba – Brenden

1

combinación de ambos hizo que para mí

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 
{ 
    if ([segue.identifier isEqualToString:@"showPopover"]) { 
     self.tableOfContentsPopoverController = [(UIStoryboardPopoverSegue*)segue popoverController]; 
    } 
} 

- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender { 
    if ([identifier isEqualToString:@"showPopover"]) { 
     if (!self.tableOfContentsPopoverController.popoverVisible) { 
      return YES; 
     } 
     return NO; 
    } 
    return YES; 
} 
Cuestiones relacionadas