11

在 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;
}

这可以很好地在按下按钮时显示弹出框。但是,如果在按钮已经打开时按下按钮,我也希望弹出框关闭以遵循良好的指导方针。我该怎么做呢?(即,如果用户反复单击此按钮,则弹出框应该会出现并隐藏所有其他点击。)

4

7 回答 7

16

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

- (void)splitViewController:(UISplitViewController*)svc popoverController:(UIPopoverController*)pc willPresentViewController:(UIViewController *)aViewController{
  if ([pc isPopoverVisible]) {
     [pc dismissPopoverAnimated:YES];
  }
}
于 2010-06-08T17:02:36.867 回答
7

Apple 的 HIG 表示,弹出框内不应有明确的关闭按钮,但要按照您的要求进行操作,您有两种选择。

1) 发布 NSNotification

或者

2)深入到您的视图层次结构,直到您有弹出实例

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 开始,进入第一个视图控制器,进入子视图,直到你到达你的 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!

希望这可以帮助

于 2010-04-22T02:03:17.777 回答
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 方法中的代码,用于在您的 splitView 的 index:0 处显示 viewController。这个答案不一定适用于此,但适用于您在 iPad 上访问和创建 popoverControllers 的任何其他时间。如果不首先检查弹出框是否可见,您将崩溃或打开多个弹出框。

谢谢你的时间。

于 2010-04-21T03:55:19.660 回答
1

你可以试试下面的

if(![popoverController isPopoverVisible]){
   // Show popover
}
else{
   // close popover
   [popoverController dismissPopoverAnimated:YES];
}
于 2010-04-17T20:54:26.690 回答
0

我用来在 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];
  }
}
于 2010-04-21T11:11:26.937 回答
0

如果您使用默认UISplitViewController设置,则创建的导航栏按钮会显示您的RootViewController.

如果您想确保您没有同时打开多个弹出窗口,您可以在弹出窗口RootViewController出现时简单地关闭弹出窗口。这是我用来解决这个问题的代码:

- (void) viewWillAppear:(BOOL)animated {
  if ([self.popover isPopOverVisible]) {
    [self.popover dismissPopoverAnimated:YES];
  }
  [super viewWillAppear:YES];
}
于 2010-05-28T05:17:39.173 回答
0

是的,您可以设置modalPresentationStyle如下:

controller.modalPresentationStyle = UIModalPresentationFormSheet;
于 2010-12-28T03:09:12.430 回答