我一直在尝试在自定义UIView子类中创建协议和委托,但是当我在View Controller类上调用它时,按钮未响应该方法。我已经阅读了关于StackOverflow的几乎所有答案,但没有一个能解决我的问题。这是我遵循的过程:

UIView子类(视图A)

创建需求委托:

protocol LoginDelegates {
    func loginButtonPressed(sender: AnyObject)
}

在子类中
class LoginViewController: UIViewController {

    @IBOutlet weak var loginButton: UIButton!

    var delegate: LoginDelegates? // Initite the delegate variable

    //Login Button Action
    @IBAction func loginButtonPressed(_ sender: UIButton) {
       delegate?.loginButtonPressed(sender: loginButton)
    }
}

视图控制器类(视图B)

在 class 中调用委托:
class AccessViewController: UIViewController, LoginDelegates

在这里,我尝试了在SO和网络上发现的多种方法。但它们似乎都不适合我,该按钮仍然没有响应。

方法1:
override func viewDidLoad() {
    super.viewDidLoad()
    //Assign the delegate in current view
    let LoginView = LoginViewController()
    LoginView.delegate = self
}

Approach 2:
通过这种方法,我得到以下错误doesn't contain a view controller with identifier 'LoginViewController',这是有道理的,因为该视图是子类而不在情节提要中。
override func viewDidLoad() {
    super.viewDidLoad()
    //Assign the delegate in current view
    if let loginView = self.storyboard?.instantiateViewController(withIdentifier: "LoginViewController") as? LoginViewController {
        loginView.delegate = self
    }

}

当然,请在当前视图中调用该方法。
func loginButtonPressed(sender: AnyObject) {
     performSegue(withIdentifier: "toDashboard", sender: self)
}

我还尝试创建一个快速文件,将所有协议从这两个视图中分离出来,并在需要时调用它们。在这一点上,我别无选择。预先感谢您的帮助。

最佳答案

像这样更新您的LoginViewController:

class LoginViewController: UIViewController {

    static weak var shared: LoginViewController?

    @IBOutlet weak var loginButton: UIButton!

    weak var delegate: LoginDelegates? // Initite the delegate variable

    //Login Button Action
    @IBAction func loginButtonPressed(_ sender: UIButton) {
       delegate?.loginButtonPressed(sender: loginButton)
    }

    override func viewDidLoad() {
       super.viewDidLoad()
       // All your viewDidLoad stuff

       LoginViewController.shared = self

    }
}

像这样更新您的AccessViewController:
class AccessViewController: UIViewController, LoginDelegates {


   override func viewDidLoad() {
      super.viewDidLoad()
      // All your viewDidLoad stuff

      LoginViewController.shared?.delegate = self

   }

   func loginButtonPressed(sender: AnyObject) {
      performSegue(withIdentifier: "toDashboard", sender: self)
   }
}

您引起的问题是因为您无权访问LoginViewController的 Activity 实例。在这两种方法中,您都将创建一个LoginViewController的新实例,但是您需要访问现有实例。为此,您必须创建静态变量,该变量将为您保留对LoginViewController的 Activity 实例的引用。

另外请记住,在大多数情况下,必须将委托变量标记为弱变量,以避免内存泄漏。

由于您直接在AccessViewController视图中加载并显示LoginViewController的视图,因此LoginViewController不是firstResponder。因此,在按下时不会调用按钮的操作。

您可以在AccessViewController类中进行一些技巧
class AccessViewController: UIViewController, LoginDelegates {


   override func viewDidLoad() {
      super.viewDidLoad()
      // All your viewDidLoad stuff

      let loginVC = LoginViewController()

      loginVC.loginButton.addTarget(self, action: #selector(self.loginButtonPressed), for: .touchUpInside)

      //add your LoginViewController view as subview to your AccessController view.

   }

   @objc func loginButtonPressed() {
      performSegue(withIdentifier: "toDashboard", sender: self)
   }
}

关于ios - 协议(protocol)委托(delegate)在自定义UIView按钮中不起作用,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49834649/

10-11 18:27