在这个特定场景中(很常见,代表了现实世界中的大多数场景),您不需要多个导航控制器。
有时,您需要在另一个之上添加一个 UINavigationController,但目前情况并非如此,因此我不会对此进行详细介绍。
您所做的基本上是在您的应用中拥有 4 种不同的“方式”。但本质上,您需要一种方法,需要 4 个步骤。
所以不要这样做
(navA --> A) (navB --> B) (navC --> C) (navD --> D)
你想做的是
Nav -> A (root of Nav) -> B -> C -> D
我看到您正在使用 Storyboard,这使得它更容易。
使用 Right clic(或 Ctrl + clic)拖放将控制器 A 连接到情节提要中的控制器 B。对 B -> C 和 C -> D 执行相同操作。
您将看到链接出现。你可以点击它们来重命名它们,给它们相关的名称。这些被称为segue。
我通常使用功能名称将它们命名为“FromXXXToYYYY”。比如“FromContactsToDetail”
您可以(但不是必须)从UIViewController 链接到UIViewController,使用情节提要中的黄色小圆圈图标,或者只需在控制器顶部拖动即可。但是您可以也可以从UIButton 拖动到UIViewController。只需从 UIButton 开始执行相同的连接(使用右键 clic 拖动或使用 ctrl + clic 拖动)。
唯一的区别是,如果您从按钮拖动,按钮将执行操作。如果从控制器拖动,则必须手动输入代码。有时您只需要通过按钮执行此操作,有时则不需要。
如果你用按钮来做,你的工作就完成了。
如果您从情节提要中执行此操作,则需要调用
PerformSegue(self, "SegueNameYouEnteredInStoryboard").
您可以在IBAction 中拨打此电话。
如果您只在 IBAction 中执行 performSegue,这可能是删除 IBAction 并仅使用情节提要连接的标志。
iOS 将为您管理导航栏、后退按钮和所有这些。
另外,回答您的具体问题:
我想知道呈现 B 视图控制器并正确从内存中删除 A 视图控制器的正确方法是什么。
如果你想导航回 A,你需要它在内存中。只需按照我的回答中的说明进行操作即可。
如果您确实不需要返回到该控制器,通常您会遵循另一种架构。
你要做的就是让你的导航控制器将你的根设为 B。而且因为 A 只是临时的(例如可能是登录屏幕),你可以将它模态加载到 A 之上, 仅当用户已注销时,例如。
这样做很简单,只需实例化您的 UIViewController 并使用 presentViewController 呈现它。
请注意,您可以显示一个 UINavigationController,例如,如果您的登录过程由多个屏幕组成。整个导航将在根导航之上,用户将能够在登录中来回切换,当一切结束时,您只需在导航控制器上调用dismissViewController 将其删除,然后all 导航堆栈内的控制器将被移除。在我的示例中,所有登录屏幕都将被清除,最后您在 root 中使用控制器“B”的导航将可见。
因此,如果这是您遇到的类似情况,并且 A 只是暂时的,但 B 是您的重要内容,那么您应该让您的 B 已经在 A 之下,A 可见且位于最顶层,然后在必要时关闭 A 和 B会出现。