【问题标题】:How to present a second ViewController & dismiss the first如何呈现第二个 ViewController 并关闭第一个
【发布时间】:2019-01-12 00:43:38
【问题描述】:

在父 ViewController 中使用以下代码,我想在第一个视图之上显示第二个视图,然后关闭第一个视图:

// Animates the next questionViewController using the first questionViewController
[previousView presentViewController:nextQuestionViewController animated:YES completion:nil];

// Dismiss the first questionViewController
[previousView dismissViewControllerAnimated:NO completion:nil];

运行时,会显示第二个视图,但不会关闭第一个视图。

【问题讨论】:

  • previousView 是导航控制器堆栈上的 viewController 还是模态显示?
  • 是的,它是模态显示的。我不知道为什么它不会关闭。
  • 从你的代码中,它只说 presentViewController:animated,而不是 presentModalViewController:animated
  • 从你的代码中,它只说 presentViewController:animated:completion:,而不是 presentModalViewController:animated:。检查消息中间的模态词。除非,presentViewController 是自定义方法,否则我们需要更多代码。
  • 从你的代码中,它只说 presentViewController:animated:completion:,而不是 presentModalViewController:animated:。检查消息中间的模态词。除非,presentViewController 是自定义方法,否则我们需要更多代码。

标签: iphone viewcontroller


【解决方案1】:

您需要先关闭“previousView”,然后显示“nextQuestionViewController”:

// Dismiss the first questionViewController
[previousView dismissViewControllerAnimated:NO completion:nil];

// Animates the next questionViewController using the first questionViewController
[previousView presentViewController:nextQuestionViewController animated:YES completion:nil];

【讨论】:

  • 遵循此答案会导致以下异常:Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Application tried to present modally an active controller <FirstViewController: 0x71cf520>.'
  • 你不认为使用视图控制器来呈现另一个视图控制器会容易出错,因为它知道它本身会在某个时间点被释放。正如@Mozilla 所建议的那样,我宁愿使用[[UIApplication sharedApplication].keyWindow.rootViewController 或类似的nextQuestionViewController
【解决方案2】:

试试

[self dismissViewControllerAnimated:NO completion:nil];

失败了:

[self.navigationController popViewControllerAnimated:YES];

【讨论】:

  • 我正在尝试再次解决这个问题 - 使用这两种方法都无法关闭第二个 viewController,在呈现第一个之后 - 我还遗漏了什么吗?
  • 正如 Raphael 所说,您应该按如下方式呈现第二个 viewController:[previousView presentModalViewController: nextQuestionViewController animated:YES];
【解决方案3】:

接下来我做了(self - 是你的旧控制器):

UIStoryboard *storyboard = self.storyboard;

[self dismissViewControllerAnimated:YES
                         completion:^{
        UIViewController *newController = [storyboard instantiateViewControllerWithIdentifier:@"newControllerStoryboardId"];
        newController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;

        [[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:newController animated:YES completion:nil];
    }];

【讨论】:

    【解决方案4】:

    使用“unwind segue”可能会更好:

    https://developer.apple.com/library/archive/featuredarticles/ViewControllerPGforiPhoneOS/UsingSegues.html#//apple_ref/doc/uid/TP40007457-CH15-SW8

    https://developer.apple.com/library/archive/technotes/tn2298/_index.html

    它允许您同时关闭多个视图控制器,而无需知道堆栈中有多少。并且所呈现的视图控制器没有特别了解它需要导航回的位置(即,您不必直接访问窗口的根视图控制器)。

    假设您有一些名为 VC1 的根视图控制器,第一个模式是 VC2,第二个模式是 VC3。

    在 VC1 中,您将实现一个名为(例如)unwindToRootIBAction。然后在 VC3 的情节提要中,将完成按钮连接到 Exit 对象并选择 unwindToRoot 操作。

    当按下该按钮时,系统将关闭所有需要的视图控制器,将您带回 VC1。

    所以基本上你只是让所有这些 VC 堆叠起来,当你都完成后,你将关闭所有内容以返回根 VC。

    【讨论】:

      【解决方案5】:

      好像从B到C不简单显示A是不行的,看起来很不专业。但是,您可以在 A 上方放置一个黑色子视图,直到您已动画到 C。

      代码见我https://stackoverflow.com/a/45579371/218226的回答

      【讨论】:

        猜你喜欢
        • 2017-12-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多