我一直在尝试在自定义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/