从self.navigationItem(UINavigationController内部)打开时,UIPopoverController不会被解雇

时间:2012-07-20 11:08:59

标签: iphone ios uinavigationcontroller uipopovercontroller dismiss

我在解决从UINavigationController的navigationItem启动的popover时遇到问题。似乎UINavigationController插入的导航项不会触发UIPopoverController的解雇。通常,当你在弹出窗口外面敲击时,它就会变暗。但是当您点击导航项时,弹出窗口不会被解除。更糟糕的是,如果你点击触发弹出窗口的按钮,你将获得弹出窗口的第二个实例。

所有这些都是使用故事板完成的: - 创建一个视图,将其嵌入到UINavigationView中,以便在顶部获得一个navigationItem。 - 将UIBarButtonItem放入navigationItem(左侧或右侧,与导航堆栈上的初始视图无关)。 - 定义另一个视图,并将一个segue从UIBarButtonItem拖到此视图中。 - 将segue设置为popover。

弹出窗口打开后,我无法通过点击navigationItem来解除它。我无法相信这“按设计工作”,所以我怀疑我错过了什么。

虽然我的目标是尽可能少地编程(这就是故事板的内容,不是吗?),我想到了解决方法:我想到的第一个解决方法是在navigationItem中添加一个UITapGestureRecognizer,当它检测到导航项上的点击时会忽略弹出窗口。不幸的是,navigationItem似乎不是UIVIew,所以它缺少addGestureRecognizer:方法......

编辑:可以在self.navigationController.navigationBar中添加UITapGesturerecognizer,但可以防止任何点击到达navigationBar上的UIBarButtonItems。是的,我本可以预料到的。

非常感谢你的帮助, 比康夫

4 个答案:

答案 0 :(得分:2)

这是故事板中弹出窗口的完整描述。假设您的控制器出现在popover中,名为MyPopupController,请执行以下操作:

  1. 使用样式MyPopupController从主场景定义到Popover场景的segue。
  2. 将属性添加到MyPopupController.h

    @property (weak, nonatomic) UIPopoverController *popover;
    
  3. MyPopupController.m

    中合成属性
    @synthesize popover = _popover
    
  4. 在主场景控制器的prepareForSegue:sender:方法中,设置popover属性:

    UIStoryboardPopoverSegue *ps = (UIStoryboardPopoverSegue *)segue;
    MyPopupController *dc = ps.destinationViewController;
    dc.popover = ps.popoverController;
    
  5. viewWillAppear:的{​​{1}}方法中,添加以下代码(不要忘记MyPopupController):

    [super viewWillAppear]
  6. 你现在应该完成。

    感谢罗伯特的基本想法 - 我必须找到正确的地方,因为在使用故事板时不使用self.popover.passThroughViews = nil; 。请注意,将(5)放入presentPopoverFromBarButtonItem不起作用。

    玩得开心!

答案 1 :(得分:1)

https://stackoverflow.com/a/12874772/1455770

从条形按钮项目呈现弹出框后,弹出窗口已将其“passthroughViews”设置为包含导航栏,因此您的水龙头不会注册。在您呈现弹出窗口后,将passthroughviews设置为nil。即

self.myPopoverController presentPopoverFromBarButtonItem:myBarButtonItem permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
self.myPopoverController.passthroughViews = nil;// at this point the myPopoverController has had its pass through views set to include the whole nav bar. remove it.

答案 2 :(得分:0)

可能有一个比这更好的解决方案,但为什么不只要在弹出窗口打开时将UITapGestureRecognizer添加到navBar?点击按钮打开弹出窗口后,将TapGestureRecogniser添加到navBar。解除弹出窗口后,从导航栏中删除TapGestureRecogniser。

答案 3 :(得分:0)

我最近遇到过这个问题,我见过的所有解决方案都没有为我工作。经过一些研究,我发现了一种像魅力一样的方式。

首先,您需要将UIStoryboardPopoverSegue添加到您的班级。

@property (nonatomic, strong) UIStoryboardPopoverSegue *popoverSegue;

在类实现中合成它:

@synthesize popoverSegue;

然后,在按下按钮时调用的函数内部添加以下代码:

([[popoverSegue popoverController] isPopoverVisible]) ? 
            [self.popoverSegue.popoverController dismissPopoverAnimated: YES] :
            [self performSegueWithIdentifier: @"popSegue" sender:nil];

现在你已经准备好了。方法内部 - (void) prepareForSegue:(UIStoryboard)segue sender:(id)sender添加以下代码:

if([[segue identifier] isEqualToString:@"popSegue"]){
    self.popoverSegue = (UIStoryboardPopoverSegue*) segue;
    if(viewPopoverController == nil){
        viewController = [[UIViewController alloc] init];
        viewPopoverController = [[UIPopoverController alloc] initWithContentViewController:viewController];
    }
}

现在,每当您按下按钮时,它将显示或关闭您的窗口,如果您在弹出窗口外按下,窗口也将被关闭。我希望它可以帮助别人。