Ios 以编程方式同时取消UINavigation视图和模态视图

Ios 以编程方式同时取消UINavigation视图和模态视图,ios,objective-c,cocoa-touch,uinavigationcontroller,storyboard,Ios,Objective C,Cocoa Touch,Uinavigationcontroller,Storyboard,我在这个网站上尝试了一些答案,但似乎都与我的问题无关 我有一个MasterDetail应用程序,它有两种类型的segues供我使用。当您按下局部视图上的按钮时,它将使用一个推送序列并将另一个局部视图推送到该视图上。在新的detailview(刚刚按下的那个)中,有一个按钮,它使用模式segue调用另一个UIView(表单表) 我试图做的是,当用户选择一行时,UIAlertView将显示一条消息,同时(不必在相同的时间)它将取消UIViewcontroller(模式),并从按下的Viewcontr

我在这个网站上尝试了一些答案,但似乎都与我的问题无关

我有一个MasterDetail应用程序,它有两种类型的segues供我使用。当您按下局部视图上的按钮时,它将使用一个推送序列并将另一个局部视图推送到该视图上。在新的detailview(刚刚按下的那个)中,有一个按钮,它使用模式segue调用另一个UIView(表单表)

我试图做的是,当用户选择一行时,UIAlertView将显示一条消息,同时(不必在相同的时间)它将取消UIViewcontroller(模式),并从按下的Viewcontroller返回。基本上,我需要能够关闭所有ViewController,一个模式和一个按钮(nav),以便视图返回到最初的主屏幕

我的UIAlertView工作正常,我可以使用
[self.dismissViewControllerAnimated:YES completion:nil]使模态viewcontroller关闭但我不知道如何关闭下一个Viewcontroller(位于导航控制器中)。使用以下命令:
[self.navigationController poptrootviewcontrolleranimated:NO]不起作用

下面是我要调用函数以删除所有视图的地方:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{

    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlWithIDAndChallenge];

    NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];

    UIAlertView *message = [[UIAlertView alloc] initWithTitle@"Started" message:@"The challenge has begun!" delegate:nil cancelButtonTitle:@"OK!" otherButtonTitles:nil];

    [message show]

    //right here is where I would normally dismiss the modal VC
    //here is where I would like to dismiss all VC

}

您可以尝试替换
[self.dismissViewControllerAnimated:YES completion:nil]带有

self dismissViewControllerAnimated:YES completion:^{
    [parentViewController.navigationController popToRootViewControllerAnimated:YES];
}

我相信parentViewController将指向演示视图控制器,并且该块将导致父视图控制器的导航控制器弹出到根视图控制器。

从您演示模式视图的类中

调用modal的DISCLISH,然后在延迟一段时间后执行选择器,然后执行以下操作:

下面是示例代码

//Write this in the class from where you presented a modal View.
//Call the function from modal class when you want to dismiss and go to root.
- (void) dismissAndGoToRoot {
      [self dismissViewControllerAnimated:YES completion:nil];
      [self performSelector:@selector(gotoRoot) withObject:nil afterDelay:0.50];
}

- (void)gotoRoot {

    [self.navigationController popToRootViewControllerAnimated:NO];
}
在这里您将调用该函数

//就在这里,我通常会忽略模态VC //这里是我想解雇所有VC的地方

[self.parentViewController dismissAndGoToRoot];
如果这不起作用,则在模式类中获取ParentViewController的实例变量,并在显示模式视图控制器时进行赋值。

如果需要,在iOS 6.0(及更高版本)项目中,可以使用展开序列。例如,您可以:

  • 在顶层视图控制器(您要展开到的控制器,而不是要从中展开的控制器)中,编写一个展开顺序方法,在本例中称为
    unwindtoplevel
    (就我个人而言,如果segue带有一些关于segue目的地的指示,我认为这很有用,因为当我们进入下面的步骤3时,这些原因将变得显而易见):

  • 在将从中启动展开的Interface Builder场景中,控制⌘-从“视图控制器”图标拖动到“退出”图标以创建展开顺序:

    通常,您会定义从按钮到出口的segue(完成了),但是如果您希望以编程方式调用segue,您可能希望在控制器和展开出口之间创建它,如上图所示

  • 您将得到一个小弹出窗口,其中包括您的放松序列的名称(来自演示控制器…就像魔术一样):

  • 如果要以编程方式调用该分段,则必须在IB窗口左侧的文档大纲中选择该展开分段,完成后,可以为该展开分段提供故事板id:

    我通常使用“展开序列号”的名称作为情节提要id,但您可以使用任何您想要的名称

  • 现在,完成此操作后,您的警报视图可以调用segue:

    - (IBAction)didTouchUpInsideButton:(id)sender
    {
        [[[UIAlertView alloc] initWithTitle:nil message:@"go home" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"OK", nil] show];
    }
    
    #pragma mark - UIAlertViewDelegate
    
    - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
    {
        if (buttonIndex != [alertView cancelButtonIndex])
        {
            [self performSegueWithIdentifier:@"unwindToTopLevel" sender:self];
        }
    }
    

  • 您支持哪些iOS版本?如果仅支持iOS 6及更高版本,您可以使用“展开”分段,这非常优雅。当我在您的问题中找到我的问题的答案时,会有这种感觉。非常感谢。好吧,我认为这段代码对我来说是正确的。我不确定如何调用它,因为我的UIAlertView(当它被解除时,应该调用您的函数)不是它自己的函数,而是在
    didSelectRowAtIndexPath
    中。当UIAlert被清除时,我将如何调用你的函数来做出反应?我将我的
    didSelectRowAtIndexPath
    添加到我的问题中谢谢你的图形化回答,它帮助很大!如果你查看我的问题的注释和编辑,你会发现我没有使用UIAlertView函数,如您所演示的。鉴于此,我将如何执行此步骤?只需将其粘贴在我放置注释的位置即可?好的,我将其粘贴在上面放置注释的位置,但什么也没有发生。在日志中,我看到以下内容:
    -[blahViewController UnwindtoLevel:
    。iAction似乎没有连接到任何东西(旁边的圆圈是空的)。这是否应该连接到某个地方?@CaptJak鉴于警报视图是异步运行的,我真的不想显示警报,然后在警报仍在显示时以及在用户解除警报之前开始解除视图(可能会起作用,但看起来像是一个奇怪的UI流)。我会在回答中这样做(在用户点击警报中的按钮之前不要切换),或者您可以让顶级控制器的
    视图显示该警报。(您可以使用一些类属性来决定是否显示警报,并在您所隔离的控制器中的
    prepareForSegue
    中进行设置。@CaptJak我不知道为什么插入
    performsguewithidentifier
    无效。如果使用此
    ClickedButtonationIndex
    技术,您必须e为
    UIAlertView
    指定
    委托
    (就像我在我的示例中所做的那样),但是如果您不想使用委托,只需在您的
    didSelectRowAtIndexPath
    中添加
    PerformsgueWithIdentifier
    行,它应该可以工作。如果不行,我不知道该说什么,因为它对我来说很好(仅在iOS 6及更高版本中)。嗯,我想这是我这边的一个PIBKAC。我把放松IBAction放在了wron中
    - (IBAction)didTouchUpInsideButton:(id)sender
    {
        [[[UIAlertView alloc] initWithTitle:nil message:@"go home" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"OK", nil] show];
    }
    
    #pragma mark - UIAlertViewDelegate
    
    - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
    {
        if (buttonIndex != [alertView cancelButtonIndex])
        {
            [self performSegueWithIdentifier:@"unwindToTopLevel" sender:self];
        }
    }