2012-09-15 32 views
1

我的问题类似于Prevent segue in prepareForSegue method?IPhone:防止popForceSecureForSegue方法?

我使用故事板,我有两个视图控制器。在第一个我有一个按钮。 而在故事板中,我有一个从按钮到第二个视图控制器的popover选项。 如果多次点击按钮,popover会多次打开。 所以这就是为什么我要检查prepareForSegue方法popover是否已经打开。如果是,则不要再打开它。那么如何在prepareForSegue方法中防止seque?

+1

将按钮连接到IBAction,您可以在其中检查弹出窗口的存在,并根据结果以编程方式执行performSegue命令。 – Rog

+0

它是用户敏感,如果我打开按钮点击弹出,比我应该被解雇的按钮点击,对不对? – Jim

+0

@Jim Yep,这是非常合乎逻辑的,如果你再次点击按钮来解除弹出窗口。看起来这是导航栏弹出的问题。无论如何,我已经用程序更新了我的答案。 – Rob

回答

2

至于答案,其他问题指出,一旦你打prepareForSegue,为时已晚取消它。你需要防止segue被第二次调用,而不是试图在segue过程中停下来。您可以通过多种方式完成此操作,具体取决于期望的行为:首先,如果您想要第二次单击该按钮以关闭弹出窗口,则可以(a)移除segue; (b)以编程方式呈现弹出窗口或将其忽略:

  1. 从故事板中删除popover segue;
  2. 为您的弹出窗口视图提供唯一的标识符,以便您可以通过代码实例化控制器;
  3. 确保您有一些IBOutlet或其他引用到您的导航栏按钮(在我的代码示例中,它是myNavBarButton),以便您可以告诉您的弹出窗口从该按钮呈现;
  4. 您可能还想将弹出窗口视图的模拟度量值更改为“自由形式”,因为如果将其保留为“推断”,Interface Builder将假定您希望它为全屏并将为您重复调整大小;
  5. 为您的popover定义了一个ivar,例如UIPopoverController *_popover;;
  6. 为您的导航栏按钮定义和链接IBAction,该按钮可根据需要进行解散或呈现弹出窗口的工作;和
  7. 确保定义视图控制器的按钮为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; 
} 
+0

禁用按钮不适合我,因为按钮位于导航栏中。当用户点击导航栏时,popover不会被解除。还有,我无法从按钮中删除popover seque,你试过了吗? Popover seque应该有视图锚点,但不能在视图控制器上) – Jim

+0

@Jim如果您愿意,可以禁用导航栏中的按钮。但考虑到你想在再次点击按钮时关闭弹出窗口,我已经用一些示例代码更新了我的答案。并且要从按钮中删除segue,您点击segue中间的图标,然后点击键盘上的'delete'键并将其删除。但是你完全正确,你不能从控制器到控制器有一个弹出窗口,所以你会在我的代码示例中看到我建议从故事板中完全删除segue,并通过代码完成所有操作。 – Rob