至于答案,其他问题指出,一旦你打prepareForSegue
,为时已晚取消它。你需要防止segue被第二次调用,而不是试图在segue过程中停下来。您可以通过多种方式完成此操作,具体取决于期望的行为:首先,如果您想要第二次单击该按钮以关闭弹出窗口,则可以(a)移除segue; (b)以编程方式呈现弹出窗口或将其忽略:
- 从故事板中删除popover segue;
- 为您的弹出窗口视图提供唯一的标识符,以便您可以通过代码实例化控制器;
- 确保您有一些
IBOutlet
或其他引用到您的导航栏按钮(在我的代码示例中,它是myNavBarButton
),以便您可以告诉您的弹出窗口从该按钮呈现;
- 您可能还想将弹出窗口视图的模拟度量值更改为“自由形式”,因为如果将其保留为“推断”,Interface Builder将假定您希望它为全屏并将为您重复调整大小;
- 为您的popover定义了一个ivar,例如
UIPopoverController *_popover;
;
- 为您的导航栏按钮定义和链接
IBAction
,该按钮可根据需要进行解散或呈现弹出窗口的工作;和
- 确保定义视图控制器的按钮为
UIPopoverControllerDelegate
,以便它可以接收和处理popoverControllerDidDismissPopover
事件。
因此,ARC的解决方案可能是:
@interface MyViewController()
{
UIPopoverController *_popover;
}
@end
@implementation MyViewController
- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController
{
_popover = nil;
}
- (IBAction)navbarButtonClicked:(id)sender
{
if (_popover)
{
// If the popover already is present, dismiss it
// I'm dismissing the popover here, but if you wanted to do something else,
// e.g. like do nothing, you could replace these two lines with whatever
// behavior you want if the user clicked on the button again.
[_popover dismissPopoverAnimated:YES];
_popover = nil;
}
else
{
// If the popover doesn't exist yet, let's create and present it
UIViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:@"gesturePopover"];
_popover = [[UIPopoverController alloc] initWithContentViewController:controller];
[_popover presentPopoverFromBarButtonItem:self.myNavBarButton permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
}
// the rest of your main view controller's implementation
@end
其次,你可以或者只是禁用导航栏按钮,这样你就不会得到popovers的顶部popovers。你也会有一个很好的视觉指示,表明它已被禁用。因此,最重要的是,您可以在执行segue之前禁用prepareForSegue
中的按钮,然后在popover解除时重新启用该按钮。您需要在Interface Builder中为您的segue定义一个标识符,并且您需要一个出口/引用到您的导航栏按钮,以便您可以启用和禁用它。然后,它将如下所示:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:@"mySegueIdentifier"])
{
UIPopoverController *popover = [(UIStoryboardPopoverSegue *)segue popoverController];
popover.delegate = self;
self.myNavBarButton.enabled = FALSE;
}
}
- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController
{
self.myNavBarButton.enabled = TRUE;
}
来源
2012-09-15 13:50:31
Rob
将按钮连接到IBAction,您可以在其中检查弹出窗口的存在,并根据结果以编程方式执行performSegue命令。 – Rog
它是用户敏感,如果我打开按钮点击弹出,比我应该被解雇的按钮点击,对不对? – Jim
@Jim Yep,这是非常合乎逻辑的,如果你再次点击按钮来解除弹出窗口。看起来这是导航栏弹出的问题。无论如何,我已经用程序更新了我的答案。 – Rob