Отключение iPad UIPopoverController, когда BarButtonItem нажата, когда он открывается

Используя разделенный вид на 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;
}

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

Ответ 1

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

- (void)splitViewController:(UISplitViewController*)svc popoverController:(UIPopoverController*)pc willPresentViewController:(UIViewController *)aViewController{
  if ([pc isPopoverVisible]) {
     [pc dismissPopoverAnimated:YES];
  }
}

Ответ 2

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

1) опубликуйте NSNotification

ИЛИ

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

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

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

создайте метод, называемый "rejectThePopover" и в методе dealloc, removeObserver

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

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

В вашей кнопке "Увольнять" нажмите кнопку "Добавить":

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

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

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

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

MyAppDelegate *appDelegate = [[UIApplication sharedApplication]delegate];
//appDelegate instance, in this case it 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 instance rootView, hereby referred to as pc.

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

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

Ответ 3

Это намного проще, потому что 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. Этот ответ не обязательно относится к этому вопросу, но применим к любому другому времени, к которому вы обращаетесь, и созданию попкорпуляторов на iPad. Не проверяя, видится ли popover первым, вы либо сработаете, либо откройте несколько popovers.

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

Ответ 4

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

if(![popoverController isPopoverVisible]){
   // Show popover
}
else{
   // close popover
   [popoverController dismissPopoverAnimated:YES];
}

Ответ 5

Код, который я использовал, чтобы показать popover в 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];
  }
}

Ответ 6

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

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

- (void) viewWillAppear:(BOOL)animated {
  if ([self.popover isPopOverVisible]) {
    [self.popover dismissPopoverAnimated:YES];
  }
  [super viewWillAppear:YES];
}

Ответ 7

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

controller.modalPresentationStyle = UIModalPresentationFormSheet;