2011-12-22 12 views
8

Attualmente ho un'app per iPad con UIToolbar contenente due UIBarButtonItems, ognuno dei quali è connesso a un seguito di popover.UIBarButtonItem + popover segue crea più popover

Quando l'utente tocca uno degli UIBarButtonItems, il popover viene creato anziché attivato. Questo crea più popover sovrapposti. Sono stato in grado di chiudere la popover creato in precedenza utilizzando il seguente codice

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

Ho anche UIButtons che creano segues popover che si comportano normalmente. A causa di questo comportamento dei popover associati a UIBarButtonItems, la mia app viene rifiutata. Qualcuno ha suggerimenti o esempi di codice di una UIToolbar con più UIBarButtonItems che funzionano correttamente? I popover vengono ignorati quando l'utente tocca fuori dalla finestra,

+0

Giusto per chiarire il mio problema. Il comportamento previsto è che ogni volta che si tocca il pulsante (UIBarButtonItem), il popover deve essere attivato o chiuso piuttosto che sempre aperto. Il seguito, tuttavia, sembra creare sempre un altro popover, piuttosto che eliminarne uno visibile. Quando sono collegati a un UIButton, i popover vengono commutati in modo appropriato. –

risposta

8

Quando si riceve un messaggio in -prepareForSegue:sender:, è troppo tardi per annullare un passaggio.

Per fare ciò in modo efficiente, è necessario creare segues per i popover dal controller di visualizzazione stesso anziché i pulsanti di barra in modo che possano essere ancora eseguiti a livello di codice. Ora collegare i valori UIBarButtonItem fino ad alcuni metodi che presenteranno o ignoreranno il popover in modo condizionale.

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

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

Grazie per il suggerimento, ci proverò! –

+1

Dopo aver provato questo suggerimento, visualizzo il seguente errore: ** Termine dell'app a causa dell'eccezione non rilevata 'NSInternalInconsistencyException', motivo: 'UIStoryboardPopoverSegue deve essere presentato da una voce del pulsante della barra o da una vista. ** –

+0

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

16

Questo è il modo corretto di fare ciò che devi fare:

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

Questo assicura che la segue verrà annullato se è già stato mostrato un esempio del popover. Devi solo assicurarti che il tuo oggetto popover abbia un identificatore nello storyboard.

+0

Se hai scelto come target 6.0+, questo è ancora l'approccio migliore. –

+0

è solo io o in ios 5 shouldPerformSegueWithIdentifier non viene chiamato? –

+0

https://developer.apple.com/library/ios/documentation/uikit/reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instm/UIViewController/shouldPerformSegueWithIdentifier:sender: sembra essere stato introdotto in iOS 6.0 e su – Brenden

1

combinazione di entrambi ha fatto per me

-(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; 
} 
Problemi correlati