子に設定されているdelegateについて以下の自分の認識が合っているか見てほしいです。
前提:
・LoginController
:子 MainTabController
:親
・画像のself.delegate?.authenticationDidComplete()
は子のLoginController
に設定されているコード
自分の認識:
・以下の画像のself.delegate?.authenticationDidComplete()
はMainTabController
にあるauthenticationDidComplete
メソッドを呼び出しいる。
//MainTabController extension MainTabController: AuthenticationDelegate { func authenticationDidComplete() { fetchUser() self.dismiss(animated: true, completion: nil) } }
全体のコード
// // LoginController.swift // InstagramFirestoreTutorial import UIKit protocol AuthenticationDelegate:class { func authenticationDidComplete() } class LoginController: UIViewController { // MARK: - Properties private var viewModel = loginViewModel() // delegateを設定 weak var delegate: AuthenticationDelegate? private let iconImage: UIImageView = { let iv = UIImageView(image: #imageLiteral(resourceName: "Instagram_logo_white") ) iv.contentMode = .scaleAspectFill return iv }() private let emailTextField: CustomTextField = { //CustomTextField クラスのplaceholder: Stringの中にEmailが入っているのか。 let tf = CustomTextField(placeholder: "Email") tf.keyboardType = .emailAddress return tf }() private let passwordTextField: CustomTextField = { let tf = CustomTextField(placeholder: "password") tf.isSecureTextEntry = true return tf }() private let loginButton: CustomUIButton = { let button = CustomUIButton(title: "loginButton") button.isEnabled = false button.addTarget(self, action: #selector(handleLogin), for: .touchUpInside) return button }() private let forgotPasswordButton: UIButton = { let button = UIButton(type: .system) button.attributedTitle(firstPart: "Forgot you password? ", secondPart: "Get help signiing in.") return button }() private let dontHaveAccountButton: UIButton = { let button = UIButton(type: .system) button.attributedTitle(firstPart: "Don't have an account", secondPart: "Sign Up") button.addTarget(self, action: #selector(handleShowSignUp), for: .touchUpInside) return button }() // MARK: - Lifecycle override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .systemPink configureUI() configureNotificationObservers() } // // override func viewDidAppear(_ animated: Bool) { // if // } // // MARK: - Actions @objc func handleLogin() { guard let email = emailTextField.text else { return } guard let password = passwordTextField.text else { return } AuthService.logUserIn(withEmail: email, password: password) { (result, error) in if let error = error { print("ログインエラー: (error.localizedDescription)") return } } self.delegate?.authenticationDidComplete() } @objc func handleShowSignUp() { // インスタンス化 let controller = RegistrationController() // controller.delegate = delegate navigationController?.pushViewController(controller, animated: true) } @objc func textDidChange(sender: UITextField) { if sender == emailTextField{ viewModel.email = sender.text } else { viewModel.password = sender.text } updateForm() } func configureUI() { configureGradientLayer() navigationController?.navigationBar.isHidden = true navigationController?.navigationBar.barStyle = .black view.addSubview(iconImage) iconImage.centerX(inView: view) iconImage.setDimensions(height: 80, width: 120) iconImage.anchor(top: view.safeAreaLayoutGuide.topAnchor,paddingTop: 32) let stack = UIStackView(arrangedSubviews: [emailTextField,passwordTextField,loginButton,forgotPasswordButton]) stack.axis = .vertical stack.spacing = 20 view.addSubview(stack) stack.anchor(top: iconImage.bottomAnchor, left: view.leftAnchor, right: view.rightAnchor, paddingTop: 32, paddingLeft: 32, paddingRight: 32) view.addSubview(dontHaveAccountButton) dontHaveAccountButton.centerX(inView: view) dontHaveAccountButton.anchor(bottom: view.safeAreaLayoutGuide.bottomAnchor) } func configureNotificationObservers() { emailTextField.addTarget(self, action: #selector(textDidChange), for: .editingChanged) passwordTextField.addTarget(self, action: #selector(textDidChange), for: .editingChanged) } } // MARK: - FormViewModel extension LoginController: FormViewModel { func updateForm() { loginButton.backgroundColor = viewModel.buttonBackgroundColor loginButton.setTitleColor(viewModel.buttonTitleColor, for: .normal) loginButton.isEnabled = viewModel.formIsValid } }
MainTabController内でdelegateで検索すると下記のものがありました。
// MainTabController.swift func checkIfUserIsLoggedIn() { if Auth.auth().currentUser == nil { print("現在のユーザーは:(Auth.auth().currentUser)です") DispatchQueue.main.async { let controller = LoginController() // 子に設定されている(LoginController())を自身にもセット controller.delegate = self let nav = UINavigationController(rootViewController: controller) nav.modalPresentationStyle = .fullScreen self.present(nav, animated: true, completion: nil) } }
delegateとして設定されたインスタンスが移譲先(delegteの言葉そのもの)になるのですが、その設定はどのようになっているのでしょうか。
こちらにもコメントありがとうございます!
ちゃんと質問の答えになっているか不安ですが、
----------------------------------------------------------------------------------------------------
// LoginController
protocol AuthenticationDelegate:class {
func authenticationDidComplete()
}
class LoginController: UIViewController {
weak var delegate: AuthenticationDelegate?
----------------------------------------------------------------------------------------------------
上記のようになっています。
どこかで、
delegate = (インスタンス名)
という宣言があると思いますが、それはどうなっているのでしょうか。
再度のご質問ありがとうございます。
そのような表記されたコードはLoginControllerファイル内になかったです。
同じような意味合いを持つコードはあるのかもしれないですが、自分の理解の範囲では見つけることができませんでした。
LoginController をインスタンス化しているコードが別のクラスにあると思いますが、それは発見できないでしょうか。
別の言い方をすると、LoginController を呼び出しているクラスのコード内に、delegate の設定があると思います(MainTabControllerのはずです)。
まずはそれを探してみてもらえますでしょうか。
ありがとうございます。
質問に修正を加えました。
ただ、別の質問でご指摘頂いたように「講座全体のコードのごく一部から推測」になってしまいそうだと思いました。
controller.delegate = selfは、self.delegate?.authenticationDidComplete()と紐付いていないコードと思えるからです。
ちゃんとした理論ではないと思うのですが、
・controller.delegate = selfをコメントアウトしてもビルドできてしまうこと
・先生がだいぶ後になってcontroller.delegate = selfを書いていたこと
です。
横から失礼します。想像ですが、udemy のその講座は、delegate とは何なのか、どうやって使うのかはある程度わかってる人向けに、実際のアプリでどんなふうに使われているかを示すものなのでしょうね。
> controller.delegate = selfは、self.delegate?.authenticationDidComplete()と紐付いていないコードと思えるからです。
あらかじめ delegate に値をセットしておき、後でその値を利用する、という一連の流れが「紐付いていない」と感じてしまうのであれば、その講座はまだ早いのでしょう。
> ・controller.delegate = selfをコメントアウトしてもビルドできてしまうこと
ビルドできるのと、ちゃんと動くのは違います。
> ・先生がだいぶ後になってcontroller.delegate = selfを書いていたこと
delegate プロパティを宣言した時点で、「これは何かを代入しなきゃいけないはずだけど、どこでやるんだろう?」と疑問を持ち、後で実際に代入する場面で、「あ、なるほど、ここで代入すればいいのか!」と納得する、という流れになってるのでしょう。
hoshi-takanoriさん、
まさに私がコメントしようとしていた内容で助かりました(地震の後片付けでそれどころではなかった)。