[英]Swift delegation problem without storyboard and segue
I have a problem with triggering a method in one Controller from another. 我在另一个控制器中触发一个控制器中的方法时遇到问题。 I set up all my elements(buttons,views..) programmatically and I'm using a
NavigationController
too. 我以编程方式设置了所有元素(按钮,视图..),我也使用了
NavigationController
。
I want to trigger fetchUsers()
method whenever a new user logs in or registers so that the tableView reloads its cells with all the users currently populating Firebase. 我想在新用户登录或注册时触发
fetchUsers()
方法,以便tableView使用当前正在填充Firebase的所有用户重新加载其单元格。
The problem is that fetchUsersDelegate?.fetchUsers()
method never gets called because loginController.fetchUsersDelegate = self
never gets set to self and always stays nil. 问题是
fetchUsersDelegate?.fetchUsers()
方法永远不会被调用,因为loginController.fetchUsersDelegate = self
永远不会设置为self,并且始终保持为零。
So my question is how should i properly set fetchUsersDelegate
? 所以我的问题是我应该如何正确设置
fetchUsersDelegate
?
First class 头等舱
class LoginController: UIViewController {
var fetchUsersDelegate: FetchUsersDelegate?
lazy var loginRegisterButton: UIButton = {
let button = UIButton()
button.backgroundColor = UIColor(r: 80, g: 101, b: 161)
button.translatesAutoresizingMaskIntoConstraints = false
button.setTitle("Register", for: .normal)
button.setTitleColor(UIColor.white, for: .normal)
button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 16)
button.layer.cornerRadius = 25
button.layer.masksToBounds = true
button.addTarget(self, action: #selector(handleLoginRegister), for: .touchUpInside)
return button
}()
@objc func handleLoginRegister(){
if loginRegisterSegmentedControl.selectedSegmentIndex == 0 {
handleLogin()
} else {
handleRegister()
}
}
func handleLogin() {
guard let email = emailTextField.text, let password = passwordTextField.text else {
print("Registration form is not valid")
return
}
Auth.auth().signIn(withEmail: email, password: password) { (user, error) in
if error != nil {
print(error!)
return
}
print("Sucessfully logged in")
self.dismiss(animated: true, completion: nil)
}
self.fetchUsersDelegate?.fetchUsers()
}
Second class 二等
class UsersController: UITableViewController, FetchUsersDelegate{
let cellID = "cellID"
var users = [User]()
let loginController = LoginController()
override func viewDidLoad() {
super.viewDidLoad()
loginController.fetchUsersDelegate = self
navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Logout", style: .plain, target: self, action: #selector(handleLogout))
checkIfUserIsLoggedIn()
}
func fetchUsers(){
Database.database().reference().child("users").observe(.childAdded, with: { (DataSnapshot) in
if let dictionary = DataSnapshot.value as? [String: AnyObject]{
let user = User()
user.name = dictionary["name"] as? String
user.email = dictionary["email"] as? String
self.users.append(user)
// if we call just tableView.reloadData the app will crash, insead we need to call it inside
// DispatchQueue.main.async
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
}, withCancel: nil)
}
Protocol 协议
protocol FetchUsersDelegate {
func fetchUsers()
}
*Edit: *编辑:
This is how i set up my rootViewController in the AppDelegate class 这是我在AppDelegate类中设置rootViewController的方式
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
FirebaseApp.configure()
window = UIWindow(frame: UIScreen.main.bounds)
window?.makeKeyAndVisible()
window?.rootViewController = UINavigationController(rootViewController: UsersController())
return true
}
And this is how i present the LoginController, the handleLogout() method is inside the UsersController if that helps. 这就是我目前使用LoginController的方式,如果有帮助,则handleLogout()方法位于UsersController内。
@objc func handleLogout(){
do{
try Auth.auth().signOut()
} catch let logoutError{
print(logoutError)
}
let loginController = LoginController()
present(loginController, animated: true, completion: nil)
}
This line 这条线
let loginController = LoginController()
is the problem it has no relation to the presented vc and it's a new separate instance , so when you present the user 是问题,它与所呈现的vc无关,并且是一个新的单独实例,因此当您呈现用户时
let user = UsersController()
self.fetchUsersDelegate = user
present// add child// user
if the user can login at same time the users table exists in screen , then i expect it's a menu list or a child vc 如果用户可以同时登录用户表存在于screen中,那么我希望它是菜单列表或子vc
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.