简体   繁体   English

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

[英]How to use Protocols and Delegates with UINavigationController

I have a Welcome controller as the base.我有一个Welcome控制器作为基础。 It presents Login or Signup controller modally based on the button the user clicks.它根据用户单击的按钮以模态方式呈现登录注册控制器。 Now once user presses login in Login controller, I dismiss the Login Controller and notify Welcome controller that user pressed login.现在一旦用户在登录控制器中按下登录,我就会关闭登录控制器并通知欢迎控制器用户按下登录。 I do this using delegates and protocols.我使用委托和协议来做到这一点。

Problem : Now the issue is that my Signup controller does not have the sign up button.问题:现在的问题是我的注册控制器没有注册按钮。 It instead directs the user to a SecondSignup controller and that directs to a ThirdSignup controller - all part of a UINavigationController .相反,它将用户定向到SecondSignup控制器,然后定向到ThirdSignup控制器 - UINavigationController 的所有部分。 How can the sign up button in this ThirdSignup controller notify the Welcome controller that user has pressed signup?这个ThirdSignup控制器中的注册按钮如何通知Welcome控制器用户已按下注册? To avoid confusion, I have specified the hierarchy below为了避免混淆,我在下面指定了层次结构

This is the Hierarchy这是层次结构

  • Welcome -> Login欢迎 -> 登录
  • Welcome -> SignUp -> SecondSignUp -> ThirdSignUp欢迎 -> 注册 -> SecondSignUp -> ThirdSignUp
protocol SignupDelegate{
      func signupButtonPressed()
}

In ThirdSignUp在第三次注册

class ThirdSignupController {
      var delegate: SignupDelegate!

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

In Welcome Controller在欢迎控制器中

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")
      }      
}
`

Simplest solution would simply be to carry on the delegate through all view controllers until the third one.最简单的解决方案就是通过所有视图控制器进行委托,直到第三个。
So define a delegate property in every view controller ( SignUp , SecondSignUp and ThirdSignUp ), and when presenting the first sign up controller, assign the delegate as the Welcome view controller.因此,在每个视图控制器( SignUpSecondSignUpThirdSignUp )中定义一个delegate属性,并在呈现第一个注册控制器时,将委托指定为Welcome视图控制器。 eg例如

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

And now for both SecondSignUp and ThirdSignUp pass on the delegate before presenting them like so:现在,对于SecondSignUpThirdSignUp在呈现它们之前传递委托,如下所示:

nextViewController.delegate = self.delegate

And by the end of this you should have your ThirdSignUp view controller have the delegate set as the Welcome view controller.最后,您应该让您的ThirdSignUp视图控制器将委托设置为Welcome视图控制器。

On a side note, it's best to use delegates as weak references to avoid retain cycles and memory leaks, especially when using the same reference through multiple controllers, so define your delegate properties like so:附带说明一下,最好将委托用作weak引用以避免保留周期和内存泄漏,尤其是在通过多个控制器使用相同的引用时,因此请像这样定义您的委托属性:

weak var delegate: SignUpDelegate

To allow that, define your protocol as:为此,请将您的协议定义为:

protocol SignUpDelegate: AnyObject { ... }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM