Skip to content

Commit

Permalink
[Refactor] 로그인 RxSwift 적용 (#11)
Browse files Browse the repository at this point in the history
  • Loading branch information
seuriseuljjeok committed Jun 7, 2024
1 parent e70631c commit 5d4ee18
Show file tree
Hide file tree
Showing 6 changed files with 229 additions and 74 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ extension UITextField {
}

//TextField 기본 속성 커스텀
func setTextField(forBackgroundColor: UIColor, forBorderColor: UIColor, forBorderWidth: CGFloat, forCornerRadius: CGFloat = 0) {
func setTextField(textfieldStatus: TextfieldStatus) {
self.clipsToBounds = true
self.layer.borderColor = forBorderColor.cgColor
self.layer.borderWidth = forBorderWidth
self.backgroundColor = forBackgroundColor
self.layer.cornerRadius = forCornerRadius
self.layer.borderColor = textfieldStatus.borderColor.cgColor
self.layer.borderWidth = textfieldStatus.borderWidth
self.backgroundColor = textfieldStatus.bgColor
self.layer.cornerRadius = textfieldStatus.borderRadius
}

//TextField placeholder 커스텀
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
//
// TextfieldStatus.swift
// Tving_CloneProject
//
// Created by 윤희슬 on 6/7/24.
//

import UIKit

protocol TextfieldStatus {

var bgColor: UIColor { get }

var borderColor: UIColor { get }

var borderWidth: CGFloat { get }

var borderRadius: CGFloat { get }

}

extension TextfieldStatus {

var borderWidth: CGFloat { return 0 }

var borderRadius: CGFloat { return 3 }
}

struct UnselectedTextfield: TextfieldStatus {

var bgColor: UIColor = UIColor(resource: .grey4)

var borderColor: UIColor = UIColor(resource: .grey4)

}

struct SelectedTextfield: TextfieldStatus {

var bgColor: UIColor = UIColor(resource: .grey4)

var borderColor: UIColor = UIColor(resource: .grey2)

var borderWidth: CGFloat = 1

}

struct CreateNicknameTextfield: TextfieldStatus {

var bgColor: UIColor = UIColor(resource: .grey2)

var borderColor: UIColor = UIColor(resource: .grey2)

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//
// ViewModelType.swift
// Tving_CloneProject
//
// Created by 윤희슬 on 6/7/24.
//

import RxSwift

protocol ViewModelType {
associatedtype Input
associatedtype Output

func transform(from input: Input, disposeBag: RxSwift.DisposeBag) -> Output
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ final class LoginView: UIView {

private let disabledButtonStatus = DisabledLoginButton()

private let unselectedTextfieldStatus: TextfieldStatus = UnselectedTextfield()


// MARK: - Life Cycles

Expand Down Expand Up @@ -109,10 +111,7 @@ private extension LoginView {
}

idTextField.do {
$0.setTextField(forBackgroundColor: UIColor(resource: .grey4),
forBorderColor: UIColor(resource: .grey4),
forBorderWidth: 0,
forCornerRadius: 3)
$0.setTextField(textfieldStatus: unselectedTextfieldStatus)
$0.setPlaceholder(placeholder: "아이디", fontColor: UIColor(resource: .grey2), font: UIFont.pretendard(.subhead3))
$0.setLeftPadding(amount: 22)
$0.textColor = UIColor(resource: .grey2)
Expand All @@ -132,10 +131,7 @@ private extension LoginView {
}

pwTextField.do {
$0.setTextField(forBackgroundColor: UIColor(resource: .grey4),
forBorderColor: UIColor(resource: .grey4),
forBorderWidth: 0,
forCornerRadius: 3)
$0.setTextField(textfieldStatus: unselectedTextfieldStatus)
$0.setPlaceholder(placeholder: "비밀번호", fontColor: UIColor(resource: .grey2), font: UIFont.pretendard(.subhead3))
$0.setLeftPadding(amount: 22)
$0.textColor = UIColor(resource: .grey2)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import UIKit

import SnapKit
import Then
import RxSwift
import RxCocoa

final class LoginViewController: UIViewController {

Expand All @@ -21,14 +23,24 @@ final class LoginViewController: UIViewController {

// MARK: - Properties

var isActivate: Bool = false
var isActivate: Bool = false {
didSet {
self.loginView.setLoginButton(isEnabled: isActivate)
}
}

var nickname: String? = nil

var loginModel: LoginModel = LoginModel(id: nil, pw: nil)

private let loginViewModel: LoginViewModel = LoginViewModel()

private let disposeBag = DisposeBag()

private let selectedTextfieldStatus: TextfieldStatus = SelectedTextfield()

private let unselectedTextfieldStatus: TextfieldStatus = UnselectedTextfield()


// MARK: - Life Cycles

Expand All @@ -39,6 +51,10 @@ final class LoginViewController: UIViewController {
setLayout()
setStyle()
setView()
setViewModel()
clearButtonTapped()
pushToWelcomeVC()
maskButtonTapped()
}

}
Expand Down Expand Up @@ -72,15 +88,7 @@ private extension LoginViewController {
func setView() {
self.loginView.do {
$0.idTextField.delegate = self
$0.idTextField.addTarget(self, action: #selector(textFieldChange), for: .editingChanged)
$0.pwTextField.delegate = self
$0.pwTextField.addTarget(self, action: #selector(textFieldChange), for: .editingChanged)
$0.loginButton.addTarget(self, action: #selector(pushToWelcomeVC), for: .touchUpInside)
$0.idClearButton.tag = 0
$0.idClearButton.addTarget(self, action: #selector(clearButtonTapped), for: .touchUpInside)
$0.pwClearButton.tag = 1
$0.pwClearButton.addTarget(self, action: #selector(clearButtonTapped), for: .touchUpInside)
$0.maskButton.addTarget(self, action: #selector(maskButtonTapped), for: .touchUpInside)
}

self.createView.do {
Expand All @@ -90,6 +98,20 @@ private extension LoginViewController {
}
}

private func setViewModel() {
let input = LoginViewModel.Input(
idTextfieldDidChangeEvent: loginView.idTextField.rx.text.asObservable(),
pwTextfieldDidChangeEvent: loginView.pwTextField.rx.text.asObservable(),
loginButtonDidTapEvent: loginView.loginButton.rx.tap.asObservable()
)

let output = loginViewModel.transform(from: input, disposeBag: disposeBag)

output.isValid.subscribe(onNext: { [weak self] isValid in
self?.isActivate = isValid ? true : false
}).disposed(by: disposeBag)
}

@objc
func presentCreateNicknameVC(sender: UITapGestureRecognizer) {
let createNicknameVC = CreateNicknameViewController()
Expand All @@ -98,61 +120,64 @@ private extension LoginViewController {
self.present(createNicknameVC, animated: true)
}

@objc
func textFieldChange() {
loginModel = LoginModel(id: self.loginView.idTextField.text, pw: self.loginView.pwTextField.text)
self.isActivate = loginViewModel.checkValid(loginInfo: loginModel)
self.loginView.setLoginButton(isEnabled: self.isActivate)
}

@objc
func maskButtonTapped() {
self.loginView.pwTextField.isSecureTextEntry = !self.loginView.pwTextField.isSecureTextEntry
loginView.maskButton.rx.tap
.subscribe(
onNext: { _ in
self.loginView.pwTextField.isSecureTextEntry = !self.loginView.pwTextField.isSecureTextEntry
}).disposed(by: disposeBag)
}

@objc
func clearButtonTapped(_ sender: UIButton) {
if sender.tag == 0 {
self.loginViewModel.clearText(textfield: self.loginView.idTextField)
} else {
self.loginViewModel.clearText(textfield: self.loginView.pwTextField)
}

func clearButtonTapped() {
loginView.idClearButton.rx.tap
.subscribe(
onNext: { _ in
self.loginViewModel.clearText(textfield: self.loginView.idTextField)
}).disposed(by: disposeBag)

loginView.pwClearButton.rx.tap
.subscribe(
onNext: { _ in
self.loginViewModel.clearText(textfield: self.loginView.pwTextField)
}).disposed(by: disposeBag)

self.isActivate = false
self.loginView.setLoginButton(isEnabled: self.isActivate)
}

@objc

func pushToWelcomeVC() {
if isActivate {
let welcomeVC = WelcomeViewController()
if loginViewModel.checkEmptyNickname(nickname: self.nickname) {
welcomeVC.userInfo = self.loginViewModel.id.value
} else {
welcomeVC.userInfo = self.loginViewModel.nickname.value
}
self.navigationController?.pushViewController(welcomeVC, animated: true)
}
loginView.loginButton.rx.tap
.subscribe(
onNext: { _ in
if self.isActivate {
let welcomeVC = WelcomeViewController()
let nickname = self.loginViewModel.fetchNickname()
if nickname.isEmpty {
welcomeVC.userInfo = self.loginViewModel.fetchId()
} else {
welcomeVC.userInfo = nickname
}
self.navigationController?.pushViewController(welcomeVC, animated: true)
}
}).disposed(by: disposeBag)
}

}

// MARK: - Delegates

extension LoginViewController: CreateNicknameVCDelegate {

func saveUserNickname(nickname: String) {
self.nickname = nickname
self.loginViewModel.nickname = nickname
}
}

extension LoginViewController: UITextFieldDelegate {

func textFieldDidBeginEditing (_ textField: UITextField) {
textField.layer.borderWidth = 1
textField.layer.borderColor = UIColor(resource: .grey2).cgColor
textField.setTextField(textfieldStatus: selectedTextfieldStatus)
}

func textFieldDidEndEditing(_ textField: UITextField) {
textField.layer.borderWidth = 0
textField.setTextField(textfieldStatus: unselectedTextfieldStatus)
}
}
Loading

0 comments on commit 5d4ee18

Please sign in to comment.