-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
✨ Feat: #40 - 비밀번호 찾기/인증코드 보내기 화면 제작
- Loading branch information
Showing
2 changed files
with
175 additions
and
0 deletions.
There are no files selected for viewing
127 changes: 127 additions & 0 deletions
127
...uth/SignIn/FindPassword/FindPasswordScrollPages/SendCertifyCode/SendCertifyCodeView.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) }) | ||
} | ||
} |
48 changes: 48 additions & 0 deletions
48
...ignIn/FindPassword/FindPasswordScrollPages/SendCertifyCode/SendCertifyCodeViewModel.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<String> | ||
} | ||
|
||
struct Output { | ||
let certifyEmail: Observable<Bool> | ||
let emailValidation: Observable<Bool> | ||
} | ||
|
||
var disposeBag: DisposeBag = DisposeBag() | ||
|
||
private var allcertifyEmailRelay = BehaviorRelay<Bool>(value: false) | ||
|
||
func transform(input: Input) -> Output { | ||
let emailValidation: Observable<Bool> = 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 | ||
) | ||
} | ||
|
||
} | ||
|