我在解决从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。是的,我本可以预料到的。
非常感谢你的帮助, 比康夫
答案 0 :(得分:2)
这是故事板中弹出窗口的完整描述。假设您的控制器出现在popover中,名为MyPopupController
,请执行以下操作:
MyPopupController
从主场景定义到Popover
场景的segue。将属性添加到MyPopupController.h
@property (weak, nonatomic) UIPopoverController *popover;
在MyPopupController.m
@synthesize popover = _popover
在主场景控制器的prepareForSegue:sender:
方法中,设置popover
属性:
UIStoryboardPopoverSegue *ps = (UIStoryboardPopoverSegue *)segue;
MyPopupController *dc = ps.destinationViewController;
dc.popover = ps.popoverController;
在viewWillAppear:
的{{1}}方法中,添加以下代码(不要忘记MyPopupController
):
[super viewWillAppear]
你现在应该完成。
感谢罗伯特的基本想法 - 我必须找到正确的地方,因为在使用故事板时不使用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];
}
}
现在,每当您按下按钮时,它将显示或关闭您的窗口,如果您在弹出窗口外按下,窗口也将被关闭。我希望它可以帮助别人。