在呈现新视图控制器后关闭当前视图控制器 - swift

Posted

技术标签:

【中文标题】在呈现新视图控制器后关闭当前视图控制器 - swift【英文标题】:dismiss current view controller AFTER presenting new view controller - swift 【发布时间】:2017-07-09 10:14:57 【问题描述】:

我正在尝试解雇一个 VC 并提出一个新的 VC。但我不希望旧的 VC 存在了。我使用下面的代码来关闭当前的 VC 并呈现新的。但是这样,在解雇和出席之间有一个时间间隔。我不希望用户注意到这一点。所以,我想先介绍新的 VC,然后再驳回之前的 VC。有没有办法做到这一点?

let storyboard = UIStoryboard(name: "Main", bundle: nil)
let destinationController = self.storyboard?.instantiateViewController(withIdentifier: "login") as! Login
let presentingVC = self.presentingViewController
self.dismiss(animated: false, completion:  () -> Void   in
    presentingVC!.present(destinationController, animated: true, completion: nil)
)

【问题讨论】:

你为什么不按顺序调用它,首先出现,然后关闭(而不是在当前的完成处理程序中)?所以:presentingVC!.present(destinationController, animated: true, completion: nil); self.dismiss(animated: false, completion:nil) 朋友,您为什么要从堆栈中删除该 currentVc? 直接你可以通过将动画设为假来关闭。 @AndreasOetjen 如果我这样做,它首先会提出并解雇新的 VC,而不是旧的 VC @Mukesh 因为我不想在用户再次返回时再次显示它。以及将动画设为 false 对我有何帮助? 【参考方案1】:

我认为最好的方法是在您真正回去时解雇当前的 VC。这意味着,使用当前 VC 展示您的 destinationController,然后当您返回时,关闭两个 VC

【讨论】:

我认为这是一个更好的主意,感谢您的帮助。【参考方案2】:

免责声明

因此,除非您绝对需要以模态方式展示您的新 VC,否则我建议您只在两个 VC 之间进行转场。您似乎只是以模态方式呈现它,因为您想稍后从原始 VC 中手动将其关闭。在我看来,使用 segue 不仅更容易,而且还允许您使用我在下面概述的方法。

解决方案

这可能不是最优雅的方法,但您可以将旧 VC 的实例通过 prepareForSegue 传递给下一个 VC,然后在新 VC 的 viewDidLoad 中将其关闭。

例如,在你的新 VC 中,你可以有这样的东西:

class NewVC: UIViewController 

    ...
    var prevVC: PrevVC!

    override func viewDidLoad() 
        super.viewDidLoad()

        prevVC.dismiss(animated: false, completion: nil)
    


所以当你的 newVC 加载时,它会关闭之前的 VC。您在 prevVC 类中需要做的就是像这样传递prepareForSegue 中的实例。

class PrevVC: UIViewController 
    ...
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) 
        if let destinationVC = segue.destination as? NewVC 

            destinationVC.prevVC = self

        
    


当然,您只需要在需要时展示 newVC,然后其他所有事情都会得到处理。

【讨论】:

看起来他正在以模态方式展示 VC,所以对展示 VC 的驳回呼叫不会也驳回展示的 VC 吗? @JohnnyAW 啊,我看到了这里的困境。没看到那个。幸运的是,他似乎只是以模态方式呈现,以便稍后可以手动将其关闭。因此,如果他只是执行一个segue,那么应该没有问题。我将编辑我的帖子以包含此信息。【参考方案3】:

如果你想从 VC A 中展示 VC B 并且想在展示时关闭 VC A,你可以使用这个代码:

您在 VC A 中编写此代码,您想从哪个 Button 中显示 VC B。

let parentVC = presentingViewController
dismiss(animated: true) 
    let vc = self.storyboard!.instantiateViewController(withIdentifier...)
    parentVC.present(vc, animated: true)`enter code here`

【讨论】:

在特定情况下它可能是错误的答案,因为它可以追溯到parentVCPresentingViewController【参考方案4】:

我的做法是两者都用

view.dismiss(animated: true, completion: nil)

presentingViewController?.presentingViewController?.dismiss(animated: true, completion: nil)

取决于之前有多少个视图控制器。因为它们都是可选的,所以当你试图关闭它们时,如果你没有它们,Xcode 不会抱怨。如果是这种情况,单个dismiss() 函数就可以正常工作。

我猜是因为我一开始就没有好的设计,它可以工作,但我认为如果你一开始就有一个好的结构,你就不会遇到这种情况。

【讨论】:

【参考方案5】:

所以我只是在 Xcode13 中尝试了这个。 VC_A 对 VC_B 做了一个 segue。我试图在转场之后解除 VC_A,并将 VC_A 传递给 VC_B 并在 VC_B 的 viewDidLoad 中解除 VC_A。当我关闭 VC_B 时,它会返回 VC_A(也打印了 deinit 并且它永远不会被调用)。

【讨论】:

以上是关于在呈现新视图控制器后关闭当前视图控制器 - swift的主要内容,如果未能解决你的问题,请参考以下文章

关闭当前的模态视图控制器,然后呈现新的模态视图控制器

在当前视图控制器下显示新的视图控制器

视图控制器不会立即关闭并呈现新的视图控制器

关闭模态视图控制器后呈现不同的视图控制器

关闭呈现的视图控制器后调用主控制器的函数

在当前可见之前关闭先前呈现的模态视图控制器