2011-12-22 3 views
8

В настоящее время у меня есть приложение для iPad с UIToolbar, содержащим два UIBarButtonItems, каждый из которых связан с popper segue.UIBarButtonItem + popover segue создает несколько popovers

Когда пользователь касается какого-либо из элементов UIBarButtonItems, popover создается, а не переключается. Это создает несколько перекрывающихся popovers. Я был в состоянии закрыть ранее созданный поповер, используя следующий код

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

У меня также есть UIButtons, которые создают поповер перетекает, которые ведут себя нормально. Из-за такого поведения popovers, связанного с UIBarButtonItems, мое приложение отклоняется. Есть ли у кого-нибудь предложения или какие-либо образцы кода UIToolbar с несколькими работами UIBarButtonItems? Попутчики увольняются, когда пользователь прикасается за окном,

+0

Просто чтобы прояснить мою проблему. Ожидаемое поведение заключается в том, что каждый раз, когда кнопка (UIBarButtonItem) затрагивается, popover должен быть переключен открытым или закрытым, а не всегда открытым. Однако segue, похоже, всегда создает другой popover, вместо того, чтобы отклонять существующий видимый. Когда они связаны с UIButton, popovers соответствующим образом переключается. –

ответ

8

К тому времени, когда вы получите сообщение в -prepareForSegue:sender:, уже слишком поздно отменять сеанс.

Для того чтобы сделать это эффективно, вы должны создавать segues для своих popovers из самого контроллера представления вместо кнопок на панели, чтобы они все еще могли быть программно выполнены. Теперь подключите UIBarButtonItem до некоторых методов, которые условно представляют или отклоняют popover.

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

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

Спасибо за подсказку, я попробую! –

+1

После того, как вы попробовали это предложение, я получаю следующую ошибку: ** Завершение приложения из-за неотображаемого исключения «NSInternalInconsistencyException», причина: «UIStoryboardPopoverSegue должен быть представлен из элемента панели или вида. ** –

+0

' - (IBAction) showPopoverA: (id) отправитель { if ([self.popoverA.popoverController isPopoverVisible]) {[self.popoverA.popoverController rejectPopoverAnimated: YES]; } [self performSegueWithIdentifier: @ "showPopoverASegue" отправитель: отправитель]; } ' –

16

Это правильный способ делать то, что вам нужно сделать:

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

Это гарантирует, что переход будет отменен, если уже отображается экземпляр пирог. Вам просто нужно убедиться, что ваш объект popover имеет идентификатор в раскадровке.

+0

Если вы ориентируетесь на 6.0+, это лучший подход. –

+0

это только я или в ios 5 shouldPerformSegueWithIdentifier вообще не называется? –

+0

https://developer.apple.com/library/ios/documentation/uikit/reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instm/UIViewController/shouldPerformSegueWithIdentifier:sender: Кажется, он был введен в iOS 6.0 и вверх – Brenden

1

Сочетание обоих сделал это для меня

-(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; 
} 
Смежные вопросы