如何弹出视图控制器和触发功能

Posted

技术标签:

【中文标题】如何弹出视图控制器和触发功能【英文标题】:How to pop view controller and trigger function 【发布时间】:2020-09-12 13:35:49 【问题描述】:

我有 2 个视图控制器:

登录屏幕 忘记密码屏幕

当完成“忘记密码”并点击“发送重置链接”时,视图控制器应该会弹出并显示一条警报/一条消息。

问题

我如何navigationController?.popViewController(animated: true) 然后在新的视图控制器中显示成功警报消息?我不知道该怎么做,所以目前没有代码可以显示。

【问题讨论】:

【参考方案1】:

这里没有“开箱即用”的解决方案,因为无法为该方法提供自动完成块。但是我们可以用不同的解决方案来做到这一点(有些是样板,有些是短的)。

1 - (最简单最快)您可以利用 popViewController 具有动画的事实,因此您可以在最后使用 CATransaction 来做一些事情。

CATransaction.begin()
navigationController?.popToViewController(self, animated: true)
CATransaction.setCompletionBlock( [weak self] in
    guard let self = self else  return 
    and do here your stuff
)
CATransaction.commit()

2 - 我的首选解决方案将创建一个自定义导航控制器并传递一个完成块。然后覆盖 PopToViewController 方法并执行完成。它提供了清晰,并且是可重复使用的

public class NavigationController: UINavigationController, UINavigationControllerDelegate

    private var completion: (() -> Void)?

    override init(rootViewController: UIViewController) 
        super.init(rootViewController: rootViewController)
        delegate = self
    

    required init?(coder aDecoder: NSCoder) 
        fatalError("init(coder:) has not been implemented")
    

    public override func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool)
    
        if self.completion != nil 
            DispatchQueue.main.async(execute: 
                self.completion?()
                self.completion = nil
            )
        
    
    

 func popViewController(animated: Bool, completion: @escaping () -> Void) -> UIViewController?
    
        self.completion = completion
        return super.popViewController(animated: animated)
    
   

【讨论】:

【参考方案2】:

您可以使用委托机制。在忘记密码视图控制器中创建一个变量alertDelegate

在忘记密码VC被推入导航控制器之前将其设置为登录屏幕视图控制器,如forgotPasswordViewController. alertDelegate = self

现在覆盖ForgotPasswordViewController 中的didMoveToParentViewController 方法并调用委托函数以显示警报。

protocol AlertDelegate 
   func showAlert()


// inside LoginViewController
extension LoginViewController : AlertDelegate 
   func showAlert() 
         // code to show the alert comes here
   


// before pushing the ForgotPasswordViewController
forgotPasswordViewController.alertDelegate = self

// inside ForgotPasswordViewController
alertDelegate: AlertDelegate?

override func didMove(toParent parent: UIViewController?) 
    if parent == nil  // When the viewController is popped from the navigation controller the parent will be nil.
       alertDelegate?.showAlert()
    

【讨论】:

我收到此错误:实例成员 'alertDelegate' 不能用于类型 'ViewControllerForgotPassword';你的意思是使用这种类型的值吗?在这一行中: ViewControllerForgotPassword.alertDelegate = self 是的。 forgotPasswordViewController 是 ForgotPasswordViewController 的一个实例。您必须在实例变量上使用它。为了更清楚,我编辑了我的答案。 你能分享一下你得到的实现和错误吗?还请检查 forgotPasswordViewController.alertDelegate = self 行中的“self”是否引用了 LoginViewController 实例,并且在弹出 ForgotPasswordVC 时调用了 showAlert() 函数

以上是关于如何弹出视图控制器和触发功能的主要内容,如果未能解决你的问题,请参考以下文章

如何在视图控制器中触发协议功能?

如何从弹出视图中关闭第二个视图控制器

将多个详细视图与拆分视图控制器一起使用

如何同时关闭和弹出视图控制器

弹出其他视图控制器时如何更改弹出视图大小

如何设置推送和弹出视图控制器流程