From 316f0a17b4e7b1bd0c238f35d21af60b7081201c Mon Sep 17 00:00:00 2001 From: "ir.__.si" Date: Mon, 20 Nov 2023 16:13:21 +0900 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Feat:=20#40=20-=20=EB=B9=84?= =?UTF-8?q?=EB=B0=80=EB=B2=88=ED=98=B8=20=EC=B0=BE=EA=B8=B0/=EC=9D=B8?= =?UTF-8?q?=EC=A6=9D=EC=BD=94=EB=93=9C=20=EB=B3=B4=EB=82=B4=EA=B8=B0=20?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20=EC=A0=9C=EC=9E=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SendCertifyCode/SendCertifyCodeView.swift | 127 ++++++++++++++++++ .../SendCertifyCodeViewModel.swift | 48 +++++++ 2 files changed, 175 insertions(+) create mode 100644 CMC/Sources/Presenter/Auth/SignIn/FindPassword/FindPasswordScrollPages/SendCertifyCode/SendCertifyCodeView.swift create mode 100644 CMC/Sources/Presenter/Auth/SignIn/FindPassword/FindPasswordScrollPages/SendCertifyCode/SendCertifyCodeViewModel.swift diff --git a/CMC/Sources/Presenter/Auth/SignIn/FindPassword/FindPasswordScrollPages/SendCertifyCode/SendCertifyCodeView.swift b/CMC/Sources/Presenter/Auth/SignIn/FindPassword/FindPasswordScrollPages/SendCertifyCode/SendCertifyCodeView.swift new file mode 100644 index 0000000..87fcaa0 --- /dev/null +++ b/CMC/Sources/Presenter/Auth/SignIn/FindPassword/FindPasswordScrollPages/SendCertifyCode/SendCertifyCodeView.swift @@ -0,0 +1,127 @@ +// +// SendCertifyCodeView.swift +// CMC +// +// Created by Siri on 11/15/23. +// Copyright © 2023 com.softsquared.cmc. All rights reserved. +// + +import Foundation + +import RxCocoa +import RxGesture +import RxSwift + +import DesignSystem +import SnapKit + +import UIKit + +final class SendCertifyCodeView: BaseView { + + // MARK: - UI + private lazy var subTitle: UILabel = { + let label = UILabel() + label.text = "가입하신 이메일을 인증해주시면\n비밀번호 재설정이 가능해요!" + label.font = DesignSystemFontFamily.Pretendard.medium.font(size: 14) + label.numberOfLines = 2 + label.textColor = DesignSystemAsset.gray500.color + label.translatesAutoresizingMaskIntoConstraints = false + return label + }() + + private lazy var emailTextField: CMCTextField = { + let textField = CMCTextField( + placeHolder: "이메일을 입력해주세요", + textFieldSubTitle: "이메일", + accessoryType: .none, + keyboardType: .emailAddress + ) + textField.translatesAutoresizingMaskIntoConstraints = false + return textField + }() + + + // MARK: - Properties + private var viewModel: SendCertifyCodeViewModel + private var parentViewModel: FindPasswordViewModel + + // MARK: - Initializers + init( + viewModel: SendCertifyCodeViewModel, + parentViewModel: FindPasswordViewModel + ) { + self.viewModel = viewModel + self.parentViewModel = parentViewModel + super.init(frame: .zero) + self.backgroundColor = CMCAsset.background.color + } + + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + // MARK: - LifeCycle + // MARK: - Methods + + override func setAddSubView() { + addSubview(subTitle) + addSubview(emailTextField) + } + + override func setConstraint() { + subTitle.snp.makeConstraints { + $0.top.equalToSuperview() + $0.leading.equalToSuperview().offset(24) + } + + emailTextField.snp.makeConstraints { + $0.top.equalTo(subTitle.snp.bottom).offset(30) + $0.leading.equalToSuperview().offset(24) + $0.trailing.equalToSuperview().offset(-24) + $0.height.equalTo(74) + } + + } + + override func bind() { + + self.rx.tapGesture() + .when(.recognized) + .withUnretained(self) + .subscribe(onNext: { owner, gesture in + let location = gesture.location(in: owner) + if !owner.isPointInsideTextField(location) { + owner.endEditing(true) + } + }) + .disposed(by: disposeBag) + + let input = SendCertifyCodeViewModel.Input( + email: emailTextField.rx.text.orEmpty.asObservable() + ) + + let output = viewModel.transform(input: input) + + Observable.combineLatest( + output.certifyEmail, + output.emailValidation + ) + .withUnretained(self) + .subscribe(onNext: { owner, isEnable in + let (certifyEmail, emailValidation) = isEnable + owner.parentViewModel.readyForNextButton.accept(certifyEmail && emailValidation) + }) + .disposed(by: disposeBag) + + } +} + +extension SendCertifyCodeView { + fileprivate func isPointInsideTextField(_ point: CGPoint) -> Bool { + // 모든 텍스트 필드를 순회하면서 탭된 위치가 텍스트 필드 내부인지 확인합니다. + let textFields = [emailTextField] + return textFields.contains(where: { $0.frame.contains(point) }) + } +} diff --git a/CMC/Sources/Presenter/Auth/SignIn/FindPassword/FindPasswordScrollPages/SendCertifyCode/SendCertifyCodeViewModel.swift b/CMC/Sources/Presenter/Auth/SignIn/FindPassword/FindPasswordScrollPages/SendCertifyCode/SendCertifyCodeViewModel.swift new file mode 100644 index 0000000..d7b6dbe --- /dev/null +++ b/CMC/Sources/Presenter/Auth/SignIn/FindPassword/FindPasswordScrollPages/SendCertifyCode/SendCertifyCodeViewModel.swift @@ -0,0 +1,48 @@ +// +// SendCertifyCodeViewModel.swift +// CMC +// +// Created by Siri on 11/15/23. +// Copyright © 2023 com.softsquared.cmc. All rights reserved. +// + +import Foundation + +import RxCocoa +import RxSwift + +import UIKit + +final class SendCertifyCodeViewModel: ViewModelType { + + struct Input { + let email: Observable + } + + struct Output { + let certifyEmail: Observable + let emailValidation: Observable + } + + var disposeBag: DisposeBag = DisposeBag() + + private var allcertifyEmailRelay = BehaviorRelay(value: false) + + func transform(input: Input) -> Output { + let emailValidation: Observable = Utility.checkEmailValidation(email: input.email, validate: .emailRegex) + + input.email + .withUnretained(self) + .subscribe(onNext: { owner, email in + owner.allcertifyEmailRelay.accept(!email.isEmpty) + }) + .disposed(by: disposeBag) + + return Output( + certifyEmail: allcertifyEmailRelay.asObservable(), + emailValidation: emailValidation + ) + } + +} +