РЕДАКТИРОВАТЬ: Эти проблемы, кажется, исправлены в iOS 7.1 / Xcode 5.1.1. (Возможно, раньше, так как я не смог протестировать все версии. Определенно после iOS 7.0, так как я тестировал ту.) Когда вы создаете переход с попсовером из UIBarButtonItem
, переход гарантирует, что нажатие на всплывающее окно снова скрывает поповер, а не показывать дубликаты. Это работает правильно для новых UIPresentationController
основанных на попугах сегментов, которые Xcode 6 создает и для iOS 8.
Поскольку мое решение может представлять исторический интерес для тех, кто все еще поддерживает более ранние версии iOS, я оставил его ниже.
Если вы сохраняете ссылку на поповерный контроллер segue, отклоняя ее перед установкой ее нового значения при повторных вызовах prepareForSegue:sender:
, все, чего вы избегаете, это проблема получения нескольких всплывающих окон с многократным нажатием кнопки - Вы все еще не можете использовать кнопку, чтобы отклонить поповер, как рекомендует HIG (и как видно в приложениях Apple и т. д.)
Вы можете воспользоваться тем, чтобы ARC обнулял слабые ссылки для простого решения, однако:
1: переход с кнопки
Начиная с iOS 5, вы не могли сделать это с помощью перехода с UIBarButtonItem
, но вы можете это сделать на iOS 6 и более поздних версиях. (В iOS 5 вам нужно будет перейти от самого контроллера представления, а затем вызвать действие кнопки performSegueWithIdentifier:
после проверки на всплывающее окно.)
2: использовать ссылку на всплывающее окно в -shouldPerformSegue...
@interface ViewController
@property (weak) UIPopoverController *myPopover;
@end
@implementation ViewController
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// if you have multiple segues, check segue.identifier
self.myPopover = [(UIStoryboardPopoverSegue *)segue popoverController];
}
- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender {
if (self.myPopover) {
[self.myPopover dismissPopoverAnimated:YES];
return NO;
} else {
return YES;
}
}
@end
3: Нет третьего шага!
Приятной особенностью использования слабой ссылки обнуления здесь является то, что после того, как контроллер поповера отключается - либо программно в shouldPerformSegueWithIdentifier:
, либо автоматически пользователем, нажимающим где-то еще за пределами поповера - ивар переходит к nil
снова, поэтому мы вернулись к нашему начальному состоянию.
Без обнуления слабых ссылок, мы также должны:
- установить
myPopover = nil
при отклонении в shouldPerformSegueWithIdentifier:
и
- установите себя в качестве делегата контроллера поповера, чтобы поймать
popoverControllerDidDismissPopover:
, а также установите там myPopover = nil
(таким образом, мы ловим, когда поповер автоматически отклоняется).