如何在 UINavigationController 中使用协议和委托

Posted

技术标签:

【中文标题】如何在 UINavigationController 中使用协议和委托【英文标题】:How to use Protocols and Delegates with UINavigationController 【发布时间】:2019-12-05 00:59:18 【问题描述】:

我有一个 Welcome 控制器作为基础。它根据用户单击的按钮以模态方式呈现 LoginSignup 控制器。现在,一旦用户在 Login 控制器中按下登录,我将关闭 Login 控制器并通知 Welcome 控制器用户按下了登录。我使用委托和协议来做到这一点。

问题:现在的问题是我的 Signup 控制器没有注册按钮。而是将用户定向到 SecondSignup 控制器,然后定向到 ThirdSignup 控制器 - UINavigationController 的所有部分。 ThirdSignup 控制器中的注册按钮如何通知 Welcome 控制器用户已按下注册?为避免混淆,我在下面指定了层次结构

这是层次结构

欢迎 -> 登录 欢迎 -> 注册 -> SecondSignUp -> ThirdSignUp
protocol SignupDelegate
      func signupButtonPressed()

在第三次注册中

class ThirdSignupController 
      var delegate: SignupDelegate!

      @objc func handleSignup
         delegate.signupButtonPressed()
         self.dismiss()
      

在欢迎控制器中

class WelcomeController: SignupDelegate 

      @objc func handleSignupButtonPressed()
         let signupController = UINavigationController(rootViewController: SignupController())
         self.present(signupController, animated: true)
         // ****
         // **** Where do I set the delegate? I am not referencing ThirdSignupController()****
         // ****
      

      func signupButtonPressed()
         print("User has pressed sign up button in ThirdSignupController")
            

`

【问题讨论】:

【参考方案1】:

最简单的解决方案就是通过所有视图控制器继续委托,直到第三个。 因此,在每个视图控制器(SignUpSecondSignUpThirdSignUp)中定义一个 delegate 属性,并在呈现第一个注册控制器时,将委托分配为 Welcome 视图控制器。例如

// WelcomeController.swift
let signupController = UINavigationController(rootViewController: SignupController())
signUpController.delegate = self

现在SecondSignUpThirdSignUp 在呈现它们之前传递代表:

nextViewController.delegate = self.delegate

到此结束时,您应该将 ThirdSignUp 视图控制器的委托设置为 Welcome 视图控制器。

附带说明,最好将委托用作weak 引用以避免保留周期和内存泄漏,尤其是在通过多个控制器使用相同引用时,因此请像这样定义您的委托属性:

weak var delegate: SignUpDelegate

为此,请将您的协议定义为:

protocol SignUpDelegate: AnyObject ...

【讨论】:

很好的解决方案,但是在我将您的答案标记为正确之前,为简单起见,我只发布了三个注册流程页面。然而,在我的应用程序中,有各种条件。例如:我验证用户的文本字段输入之一,并根据该输入,呈现不同的控制器。你认为委托和协议在这里是一个优雅的解决方案吗?还是我应该去找通知和观察者? 通知和观察者从来都不是优雅的解决方案,因为它们是间接的,因此难以跟踪,并且通常是不好的使用习惯。如果没有其他选择,您应该真正使用通知。不过,另一个简单的解决方案是闭包,您可以说它本质上是另一种形式的委托,您实际上可以将它与委托一起使用。查找更多信息。祝你好运;)

以上是关于如何在 UINavigationController 中使用协议和委托的主要内容,如果未能解决你的问题,请参考以下文章

在 UINavigationController 中设置时图像不显示

将 managedObjectContext 发送到 viewController 崩溃

ID:[...] 的 NSManagedObject 已失效

使用 UINavigationController 从另一个控制器更新或重新加载 UIViewController?

为啥我似乎必须在 iOS 应用程序委托中键入 window.rootViewController?

UINavigationController - 何时释放推送的视图控制器等