diff --git a/SOPTving/SOPTving/Presentation/AuthScene/View/AuthTextField.swift b/SOPTving/SOPTving/Presentation/AuthScene/View/AuthTextField.swift index d0606cd..fe6a240 100644 --- a/SOPTving/SOPTving/Presentation/AuthScene/View/AuthTextField.swift +++ b/SOPTving/SOPTving/Presentation/AuthScene/View/AuthTextField.swift @@ -10,15 +10,15 @@ import UIKit import SnapKit import Then -protocol AuthTextFieldDelegate: UITextFieldDelegate { +protocol AuthTextFieldDelegate: AnyObject { func authTextFieldTextDidChange(_ textFieldType: AuthTextField.TextFieldType, text: String) + func authTextFieldDidReturn(_ textFieldType: AuthTextField.TextFieldType) } final class AuthTextField : UITextField { //MARK: - Properties - weak var authDelegate: AuthTextFieldDelegate? enum TextFieldType { case email @@ -38,6 +38,8 @@ final class AuthTextField : UITextField { } private var textFieldType: TextFieldType + weak var authDelegate: AuthTextFieldDelegate? + //MARK: - UI Components @@ -153,7 +155,7 @@ extension AuthTextField: UITextFieldDelegate { } func textFieldShouldReturn(_ textField: UITextField) -> Bool { - endEditing(true) + authDelegate?.authTextFieldDidReturn(textFieldType) return true } @@ -162,8 +164,8 @@ extension AuthTextField: UITextFieldDelegate { } func textFieldDidChangeSelection(_ textField: UITextField) { - updateClearButtonUI() guard let text = textField.text else { return} + updateClearButtonUI() authDelegate?.authTextFieldTextDidChange(textFieldType, text: text) } diff --git a/SOPTving/SOPTving/Presentation/AuthScene/ViewContoller/SignInVC.swift b/SOPTving/SOPTving/Presentation/AuthScene/ViewContoller/SignInVC.swift index ab6ff20..7c0ea7b 100644 --- a/SOPTving/SOPTving/Presentation/AuthScene/ViewContoller/SignInVC.swift +++ b/SOPTving/SOPTving/Presentation/AuthScene/ViewContoller/SignInVC.swift @@ -6,7 +6,6 @@ // import UIKit -import Combine import SnapKit import Then @@ -33,20 +32,7 @@ final class SignInVC: UIViewController { $0.textColor = .white } - // 빌더패턴 - // 그냥 TextField에 프로퍼티 줄어든 버전이랄까 - // 기본 프로퍼티만 추가할땐 그닥 효율성 못느낌. - // addRightButton 과 같은 함수 추가할땐 좋은 패턴인듯. - private let emailTextField = AuthTextFieldBuilder(viewType: .email) - .setText(color: .white, font: .tvingSemiBold(ofSize: 16)) - .setPlaceholder(text: "아이디", color: .tvingLightGray) - .setLeftPaddingAmount(22) - .setCornerRadius(6) - .addRightButton(.clearButton) - .build() - - // 빌더 패턴에 디럭터 패턴까지 적용시킨 버전 - // 디렉터까지 하면 모듈화하긴 좋을듯 + private let emailTextField = AuthTextFieldDirector().buildEmailTextField() private let passwordTextField = AuthTextFieldDirector().buildPasswordTextField() private lazy var signInButton = UIButton().then { @@ -69,12 +55,19 @@ final class SignInVC: UIViewController { super.viewDidLoad() delegate() - binding() + bind() + style() hierarchy() layout() } + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + + emailTextField.becomeFirstResponder() + } + required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } @@ -89,28 +82,21 @@ extension SignInVC { passwordTextField.authDelegate = self } - private func binding() { + private func bind() { viewModel.ableToSignIn.observe(on: self) { [weak self] isEnabled in self?.updateSignInButtonUI(isEnabled) } + viewModel.isSuccessLogin.observe(on: self) { [weak self] result in switch result { case .success(_): self?.goToMainVC() case .failure(let error): - switch error { - case .invalidEmail: - self?.presentBottomAlert("이메일 형식이 맞지 않습니다.") - case .invlidPassword: - self?.presentBottomAlert("비밀번호를 8자 이상 입력해주세요.") - case .invalidUser: - self?.presentBottomAlert("존재하지 않는 회원입니다.") - } + self?.presentTopAlert(error.message) } } } - // 이부분을 뷰모델이 했으면 좋겠다 private func updateSignInButtonUI(_ isEnabled: Bool) { let backgroundColor: UIColor = isEnabled ? .tvingRed : .black @@ -135,6 +121,7 @@ extension SignInVC { @objc private func signInButtonDidTap() { + view.endEditing(true) viewModel.signInButtonDidTapEvent() } } @@ -188,10 +175,23 @@ extension SignInVC { } } +//MARK: - AuthTextFieldDelegate + extension SignInVC: AuthTextFieldDelegate { + + func authTextFieldDidReturn(_ textFieldType: AuthTextField.TextFieldType) { + switch textFieldType { + case .email: + passwordTextField.becomeFirstResponder() + case .password: + view.endEditing(true) + signInButtonDidTap() + } + } + + func authTextFieldTextDidChange(_ textFieldType: AuthTextField.TextFieldType, text: String) { switch textFieldType { - case .email: self.viewModel.emailTextFieldDidChangeEvent(text) case .password: diff --git a/SOPTving/SOPTving/Utility/Builder/AuthTextFieldBuilder.swift b/SOPTving/SOPTving/Utility/Builder/AuthTextFieldBuilder.swift index a6f0737..24b8046 100644 --- a/SOPTving/SOPTving/Utility/Builder/AuthTextFieldBuilder.swift +++ b/SOPTving/SOPTving/Utility/Builder/AuthTextFieldBuilder.swift @@ -79,12 +79,12 @@ final class AuthTextFieldDirector { self.builder = builder } - func buildIDTextField() -> AuthTextField { + func buildEmailTextField() -> AuthTextField { builder = AuthTextFieldBuilder(viewType: .email) - .setLeftPaddingAmount(20) - .setText(color: .white, font: .tvingMedium(ofSize: 16)) + .setText(color: .white, font: .tvingSemiBold(ofSize: 16)) .setPlaceholder(text: "아이디", color: .tvingLightGray) + .setLeftPaddingAmount(22) .setCornerRadius(6) .addRightButton(.clearButton) guard let builder else { return AuthTextField() } diff --git a/SOPTving/SOPTving/Utility/Extension/UIViewController+.swift b/SOPTving/SOPTving/Utility/Extension/UIViewController+.swift index 2766c22..6329ca2 100644 --- a/SOPTving/SOPTving/Utility/Extension/UIViewController+.swift +++ b/SOPTving/SOPTving/Utility/Extension/UIViewController+.swift @@ -62,6 +62,54 @@ extension UIViewController{ ) } + func presentTopAlert(_ message: String) { + + let alertSuperview : UIView = { + let view = UIView() + view.backgroundColor = .darkGray.withAlphaComponent(0.85) + view.layer.cornerRadius = 10 + view.isHidden = true + return view + }() + + + let alertLabel : UILabel = { + let label = UILabel() + label.font = .systemFont(ofSize: 15) + label.textColor = .white + label.text = message + return label + }() + + view.addSubview(alertSuperview) + alertSuperview.addSubview(alertLabel) + alertSuperview.snp.makeConstraints { + $0.centerX.equalToSuperview() + $0.top.equalTo(view.safeAreaLayoutGuide).offset(35) + $0.leading.trailing.equalToSuperview().inset(20) + $0.height.equalTo(40) + } + + alertLabel.snp.makeConstraints { + $0.center.equalToSuperview() + } + + + alertLabel.text = message + alertSuperview.alpha = 1.0 + alertSuperview.isHidden = false + + UIView.animate( + withDuration: 2.0, + delay: 1.0, + options: .curveEaseIn, + animations: { alertSuperview.alpha = 0 }, + completion: { _ in + alertSuperview.removeFromSuperview() + } + ) + } + func addKeyboardNotifications(){ // 키보드가 나타날 때 앱에게 알리는 메서드 추가