我一直在尝试在我的自定义UIView子类中创建协议和委托,但是当我在View Controller类上调用它时,按钮没有响应该方法。我已经阅读了StackOverflow上的几乎所有答案,但没有一个能解决我的问题。这是我遵循的程序:
创建需要委托:
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)
}
}
在班级内呼叫代表:
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)
}
我还尝试创建一个swift文件,只是将所有协议与两个视图分开,并在需要时调用它们。而在这一点上,我别无选择。提前谢谢你的帮助。
答案 0 :(得分:2)
像这样更新你的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的活动实例而导致的问题。在这两种方法中,您都创建了一个新的LoginViewController实例,但您需要访问现有实例。为此,您必须创建静态变量,它将为您提供对LoginViewController的活动实例的引用。
另请注意,在大多数情况下,您必须将委托变量标记为弱以避免内存泄漏。
由于您在AccessViewController视图中直接加载并显示LoginViewController的视图,因此您的LoginViewController不是第一个响应者。因此,按下时不会调用按钮的操作。
您可以在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)
}
}