[英]How do I set delegate = self when I only want communication from one controller to the other
所以我有一個從 MainController() 呈現的 LoginController()。 所以從技術上講 MainController() 仍然在后台加載並在內存中。 現在在 LoginController() 中,當我按下登錄按鈕時,我想通知 MainController() 登錄按鈕被按下,以便再次獲取當前用戶。 然后我關閉 LoginController()。
我想用協議和委托來做到這一點,但問題是當 MainController() 符合 LoginDelegate 時,我不知道如何將委托設置為 self。 因為當用戶注銷或沒有用戶時,我不想回到登錄控制器,我想回到不同的 WelcomeController()。 如果我想去 LoginController() 那么我知道我可以做到
let loginController = LoginController()
loginController.delegate = self
self.present(loginController)
但就我而言,我想使用完全不同的控制器。 那么我在哪里將委托設置為自我?
這是代碼:
//LoginController()
protocol LoginDelegate {
func didTapLogIn()
}
class LoginController: UIViewController, UITextFieldDelegate{
var loginDelegate: LoginDelegate!
override func viewDidLoad() {
super.viewDidLoad()
configureViews()
formValidation()
}
@objc func handleLogin(){
guard let email = emailTextField.text else {return}
guard let password = passwordTextField.text else {return}
Auth.auth().signIn(withEmail: email, password: password) { (auth, error) in
if let error = error{
print("There was a problem signing the user in", error.localizedDescription)
return
}
self.loginDelegate.didTapLogIn()
print("Successfully signed in the user")
self.dismiss(animated: true, completion: nil)
}
}
}
這是符合的 MainController
//MainController() which is a tab bar controller
class MainController: UITabBarController, LoginDelegate {
override func viewDidLoad() {
super.viewDidLoad()
checkLoggedInUserStatus()
}
fileprivate func checkLoggedInUserStatus(){
if Auth.auth().currentUser == nil{
DispatchQueue.main.async {
let welcomeController = UINavigationController(rootViewController: WelcomeController())
welcomeController.modalPresentationStyle = .fullScreen
self.present(welcomeController, animated: false, completion: nil)
return
}
} else {
setupTabBar()
}
}
fileprivate func setupTabBar(){
tabBar.isTranslucent = false
tabBar.barTintColor = TDGOtherBlue
let homeController = HomeController()
homeController.fetchCurrentUser()
let homeViewController = UINavigationController(rootViewController: homeController)
let chatViewController = UINavigationController(rootViewController: EditProfileController())
viewControllers = [homeViewController, chatViewController]
}
func didTapLogIn() {
checkLoggedInUserStatus()
}
}
//NOTE: ABOVE IS THE DELEGATED FUNCTION BUT WHERE DO I DO THE DELEGATE SELF DECLARATIOn
筆記:
你的建築看起來像一杯雞尾酒。 但是,盡管如此,請注意:
weak var loginDelegate: LoginDelegate? // should be weak and optional
使用此流程:
self.dismiss(animated: true) {
self.loginDelegate.didTapLogIn()
print("Successfully signed in the user")
}
你沒有描述什么是Auth
,
有些你不能保證
Auth.auth().currentUser
實際上不是 nil
甚至在這里:
@objc func handleLogin(){
//....
Auth.auth().signIn( ... {
///here
/// check it!
})
所以,如果沒有,請使用
protocol LoginDelegate {
func didTapLogIn(user: User)
}
反而
編輯
很明顯,如果在 LoginViewController 關閉時你什么都沒有,你可以將數據發送到 AppDelegate。
final class AppDelegate: UIResponder {
}
extension AppDelegate: LoginDelegate { ... }
要檢索 AppDelegate 共享實例,您可以使用:
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
第二種解決方案,您可以使用 AppDelegate 獲取您的視圖控制器。 這邊走:
let rootViewController = appDelegate.window?.rootViewController
我不知道如何將委托設置為自我。 因為當用戶注銷或沒有用戶時,我不想回到登錄控制器,我想回到不同的 WelcomeController()。
聽起來 MainController 真的在運行這個節目。 您還沒有對 WelcomeController 說太多,但聽起來流程是這樣的:
所以答案是 MainController 在步驟 4 中將自己設置為 LoginController 的委托,介於創建和顯示 LoginController 之間。
您需要從准備函數中分配委托值。 或者,如果您不想使用故事板/xib,您可以從您的 ViewController 中分配具有 initialize RedScreenVC(self) 的委托。
import UIKit
class ViewController: UIViewController, NavDelegate {
func navigate(text: String, isShown: Bool) {
print("text: \(text) isShown: \(isShown)")
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if (segue.identifier == "RedScreenVC") {
let redScreenVC = segue.destination as? RedScreenVC
redScreenVC?.delegate = self
}
}
@IBAction func nextPageButtonEventLustener(_ sender: Any) {
performSegue(withIdentifier: "RedScreenVC", sender: sender)
}
}
import UIKit
protocol NavDelegate {
func navigate(text: String, isShown: Bool)
}
class RedScreenVC: UIViewController {
weak var delegate: NavDelegate?
var redView = UIView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height))
var navigateButton: UIButton = {
let button = UIButton(frame: CGRect(x: 200, y: 350, width: 150, height: 50))
button.setTitle("Navigate", for: .normal)
button.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)
button.backgroundColor = .blue
return button
}()
@objc func buttonAction(){
if self.redView.backgroundColor == .gray {
self.redView.backgroundColor = .systemPink
}
self.delegate.navigate(text:"", isShown: true)
}
override func viewDidLoad() {
navigateButton.layer.cornerRadius = 25
redView.backgroundColor = UIColor.gray
delegate.navigate(text: "Navigation Success", isShown: true)
view.addSubview(redView)
view.addSubview(navigateButton)
}
}
如果您不想使用故事板並像這樣初始化
讓 redScreenVC = RedScreenVC()
redScreenVC.delegate = self
class RedScreenVC: UIViewController {
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
init() {
super.init(nibName: nil, bundle: nil)
self.initialize()
}
func initialize() {
self.view.backgroundColor=CustomColor.PAGE_BACKGROUND_COLOR_1
//From here you need to create your email and password textfield
}
}
let vc = FirstViewController.instantiate(fromStoryboard: .Profile)
vc.callback = { (address, lat, lon) in
self.updateLocation(address: address ?? "", lat: lat ?? 0.0, lon: lon ?? 0.0)
}
self.navigationController?.pushViewController(vc, animated: true)
然后在第二個VC
var callback : (( address: String?, latitude: Double?,_ longitude: Double?)-> Void)!
然后,當您想將該值傳遞回之前的 VC 時,請在單擊或解除事件中添加。
callback(address,Double(lat),Double(lon))
在視圖和控制器之間必須進行委派。 您應該在這種情況下使用Notification。
在callback
發布通知:
,,,
Auth.auth().signIn(withEmail: email, password: password) { (auth, error) in
if let error = error{
print("There was a problem signing the user in", error.localizedDescription)
return
}
// self.loginDelegate.didTapLogIn() // user didn't tap anything here! this is the callback!
print("Successfully signed in the user")
NotificationCenter.default.post(.init(name: .init(rawValue: "LoggedStatusChanged")))
self.dismiss(animated: true, completion: nil)
}
在任何需要的地方(例如MainController
)觀察此通知:
,,,
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(checkLoggedInUserStatus), name: .init(rawValue: "LoggedStatusChanged"), object: nil)
,,,
}
@objc private func checkLoggedInUserStatus() {
,,,
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.