Отключение iPad UIPopoverController при нажатии на BarButtonItem, пока он открыт - PullRequest
11 голосов
/ 15 апреля 2010

Используя разделенное представление на iPad, у меня есть следующий код:

- (void) splitViewController:(UISplitViewController *)svc willHideViewController:(UIViewController *)aViewController withBarButtonItem:(UIBarButtonItem *)barButtonItem forPopoverController:(UIPopoverController *)pc {
  barButtonItem.title = @"Categories";
  NSMutableArray *items = [[toolbar items] mutableCopy];
  [items insertObject:barButtonItem atIndex:0];
  [toolbar setItems:items animated:YES];
  [items release];
  self.popoverController = pc;
}

Это хорошо работает для отображения всплывающего окна при нажатии кнопки. Тем не менее, я также хотел бы, чтобы всплывающее окно отклонялось, если кнопка нажата, когда она уже открыта, чтобы следовать хорошим рекомендациям. Как бы я поступил так? (т. е. если пользователь несколько раз нажимает эту кнопку, всплывающее окно должно появиться и скрыть все остальные нажатия.)

Ответы [ 7 ]

16 голосов
/ 08 июня 2010

Когда splitViewController отображает всплывающее окно, будет вызван метод ниже Просто проверьте, если не ноль, то отклоните его:)

- (void)splitViewController:(UISplitViewController*)svc popoverController:(UIPopoverController*)pc willPresentViewController:(UIViewController *)aViewController{
  if ([pc isPopoverVisible]) {
     [pc dismissPopoverAnimated:YES];
  }
}
7 голосов
/ 22 апреля 2010

Apple, HIG говорит, что не должно быть явной кнопки отклонения внутри поповера, но чтобы сделать то, что вы просите, у вас есть два варианта.

1) опубликовать NSNotification

OR

2) углубиться в иерархию представлений, пока у вас не появится экземпляр popover

1) в любом представлении, в котором вы представляете всплывающее окно, в методе viewDidLoad:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(dismissThePopover) name:@"popoverShouldDismiss" object:nil];

создайте метод с именем dismissThePopover, а в методе dealloc - removeObserver

-(void)dismissThePopover {
    [self.popoverController dismissPopoverAnimated:YES];
}

-(void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

Введите в вашей строке popoverController кнопку «dismiss»:

[[NSNotificationCenter defaultCenter] postNotificationName:@"popoverShouldDismiss" object:nil];

После этого отправляется уведомление приложению, и поскольку вы зарегистрировали другой контроллер представления для его прослушивания, всякий раз, когда он видит это уведомление, он вызывает указанный вами селектор, в данном случае dismissThePopover.

2) углубиться в иерархию представлений, чтобы найти self.popoverController

зацените, у вас все будет иначе, конечно, но общая идея та же. Начните с вашего AppDelegate, перейдите к первому viewcontroller, перейдите к подпредставлениям, пока не доберетесь до своего объекта self.popoverController.

MyAppDelegate *appDelegate = [[UIApplication sharedApplication]delegate];
//appDelegate instance, in this case it's the .m file for your ApplicationDelegate

UISplitViewController *svc = appDelegate.splitViewController;
//In this case the first view inside the appDelegate is a SplitView, svc

UINavigationController *navc = [[svc viewControllers]objectAtIndex:0];
//a navigationController is at index:0 in the SplitView hierarchy. DetailView is at index:1

NSArray *vcs = [navc viewControllers];
//vcs is the array of different viewcontrollers inside the Navigation stack for nvc

iPadRootViewController *rootView = [vcs objectAtIndex:0];
//declare the rootView, which is the .m file that is at index:0 of the view array

UIPopoverController *pc = [rootView popoverController];
//HERE WE GO!!! popoverController is a property of iPadRootViewController's instance rootView, hereby referred to as pc.

[pc dismissPopoverAnimated:YES];
//bye bye, popoverController!

Надеюсь, это поможет

3 голосов
/ 21 апреля 2010

Это намного проще, потому что popoverController - это свойство. Упрощает ссылки.

if ([self.popoverController isPopoverVisible]) {
    //using the setters and getters "goes thru the proper channels" when accessing objects
    [self.popoverController dismissPopoverAnimated:YES];
} else {
    UIPopoverController *pc = [[UIPopoverController alloc] initWithContentViewController:YOUR_VIEW_CONTROLLER];
    self.popoverController = pc;
    [pc release];

    //get the button instance you set on the toolbar
    UIBarButtonItem *categoryButton = [[toolbar items] objectAtIndex:0];
    [self.popoverController presentPopoverFromBarButtonItem:categoryButton permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}

На самом деле я только что понял, что вы ссылаетесь на код внутри метода Delegate для отображения viewController с индексом: 0 вашего splitView. Этот ответ не обязательно относится к этому, но относится к любому другому времени, когда вы получаете доступ и создаете popoverController на iPad. Не проверяя, виден ли всплывающий элемент первым, вы либо аварийно завершите работу, либо откроете несколько всплывающих окон.

Спасибо за ваше время.

1 голос
/ 18 апреля 2010

Вы можете попробовать ниже

if(![popoverController isPopoverVisible]){
   // Show popover
}
else{
   // close popover
   [popoverController dismissPopoverAnimated:YES];
}
0 голосов
/ 28 декабря 2010

Да, вы можете установить modalPresentationStyle следующим образом:

controller.modalPresentationStyle = UIModalPresentationFormSheet;
0 голосов
/ 28 мая 2010

Если вы используете настройку UISplitViewController по умолчанию, то созданная кнопка панели навигации отображает всплывающее окно вашего RootViewController.

Если вы хотите убедиться, что у вас нет нескольких всплывающих окон одновременно, вы можете просто отклонить всплывающие окна всякий раз, когда появится ваш RootViewController. Вот код, который я использовал для решения этой проблемы:

- (void) viewWillAppear:(BOOL)animated {
  if ([self.popover isPopOverVisible]) {
    [self.popover dismissPopoverAnimated:YES];
  }
  [super viewWillAppear:YES];
}
0 голосов
/ 21 апреля 2010

Код, который я использовал для отображения всплывающего окна в RootViewController.m:

- (IBAction) addCategory:(id)sender {
  AddCategoryViewController *content = [[AddCategoryViewController alloc] init];
  UIPopoverController *aPopover = [[UIPopoverController alloc]
                                   initWithContentViewController:content];

  aPopover.delegate = self;

  // Store the popover in a custom property for later use.
  self.addCategoryPopover = aPopover;
  addCategoryPopover.delegate = self;
  [aPopover release];
  [content release];

  [addCategoryPopover presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
}

Это я пытался исключить из другого класса:

-(IBAction)saveAddCategory:(id)sender {
  rootViewController = [[RootViewController alloc] init];
  [rootViewController dismissPopover];
}

Моя dismissPopover функция выглядит так:

- (void) dismissPopover {
  if ([self.addCategoryPopover isPopoverVisible]) {
    [self.addCategoryPopover dismissPopoverAnimated:YES];
  }
  if (addCategoryPopover.popoverVisible == YES) {
    [addCategoryPopover dismissPopoverAnimated:YES];
  }
}
...