当巴布托尼姆被按下时,解除iPad的超控';它开着

当巴布托尼姆被按下时,解除iPad的超控';它开着,ipad,user-interface,uisplitviewcontroller,uipopovercontroller,dismiss,Ipad,User Interface,Uisplitviewcontroller,Uipopovercontroller,Dismiss,使用iPad上的拆分视图,我有以下代码: - (void) splitViewController:(UISplitViewController *)svc willHideViewController:(UIViewController *)aViewController withBarButtonItem:(UIBarButtonItem *)barButtonItem forPopoverController:(UIPopoverController *)pc { barButtonI

使用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应该会出现并隐藏每一次点击。)

您可以尝试以下方法

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

这要容易得多,因为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];
}
实际上,我刚刚意识到您指的是委托方法中的代码,用于在splitView的索引0处显示viewController。这个答案并不一定适用于这一点,但也适用于在iPad上访问和创建PopOvercontroller的任何其他时间。如果不先检查一个弹出框是否可见,您将崩溃或打开多个弹出框


谢谢您的时间。

我用来在RootViewController.m中显示popover的代码:

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

苹果公司的HIG表示,popover中不应该有一个明确的关闭按钮,但要按你的要求去做,你有两个选择

1) 张贴通知

2) 深入查看视图层次结构,直到获得popover实例 1) 无论在哪个视图中显示popover,都可以使用viewDidLoad方法:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(dismissThePopover) name:@"popoverShouldDismiss" object:nil];
创建一个名为“dismissthepover”的方法,并在dealloc方法中,removeObserver

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

-(void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}
在popoverController的“解除”按钮中,输入以下行:

[[NSNotificationCenter defaultCenter] postNotificationName:@"popoverShouldDismiss" object:nil];
这样做会向应用程序发送一个通知,并且由于您已经注册了另一个视图控制器来侦听该通知,因此每当它看到该通知时,它都会调用您指定的选择器,在本例中,它会解除该端口

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!

希望这对您有所帮助

如果您正在使用默认的
UISplitViewController
设置,则创建的导航栏按钮将显示
RootViewController
的弹出窗口

如果要确保不同时打开多个弹出窗口,只要在出现
RootViewController
时关闭弹出窗口即可。下面是我用来解决这个问题的代码:

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

当splitViewController显示popover时,将调用下面的方法。 只需检查是否为零,然后将其忽略:)


是的,您可以如下设置
modalPresentationStyle

controller.modalPresentationStyle = UIModalPresentationFormSheet;

我试图在我的iPad上创建一个popover,而不是从工具栏上,然后从其中的一个按钮上取消它。我现在才意识到我粘贴的代码是错误的。谢谢,我以前使用过通知,这次我肯定会再次尝试这种方法。这是唯一一个真正解决了原始问题的答案,它专门用于UISplitViewController创建的弹出框和工具栏项。为我解决了这个问题,谢谢。你应该使用popover属性isPopoverVisible来检查,而不是检查nil@OOP_Master感谢您的更正,我相应地更新了样本:D
controller.modalPresentationStyle = UIModalPresentationFormSheet;