Skip to content

Commit

Permalink
Merge pull request #120 from WhereAreYouPJ/feat/home
Browse files Browse the repository at this point in the history
Refactor(#103): SignUpView 리팩토링 완료
  • Loading branch information
jungseok-corine authored Feb 10, 2025
2 parents 24d13d3 + 747e569 commit 3dcc65c
Show file tree
Hide file tree
Showing 9 changed files with 184 additions and 65 deletions.
4 changes: 2 additions & 2 deletions Where_Are_You.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -2551,7 +2551,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 1;
CURRENT_PROJECT_VERSION = 3;
DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 8CKPNKA3V9;
GENERATE_INFOPLIST_FILE = YES;
Expand Down Expand Up @@ -2594,7 +2594,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 1;
CURRENT_PROJECT_VERSION = 3;
DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 8CKPNKA3V9;
GENERATE_INFOPLIST_FILE = YES;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,12 @@ class SignUpFormViewController: UIViewController {
}

private func setupActions() {
signUpView.bottomButtonView.button.addTarget(self, action: #selector(startButtonTapped), for: .touchUpInside)
signUpView.bottomButtonView.addTarget(self, action: #selector(startButtonTapped), for: .touchUpInside)
signUpView.emailCheckButton.addTarget(self, action: #selector(authRequestButtonTapped), for: .touchUpInside)
signUpView.authCheckButton.addTarget(self, action: #selector(authCheckButtonTapped), for: .touchUpInside)

signUpView.userNameTextField.addTarget(self, action: #selector(textFieldDidChange(_:)), for: .editingDidEnd)
signUpView.userNameTextField.addTarget(self, action: #selector(textFieldDidChange(_:)), for: .editingChanged)
signUpView.emailTextField.addTarget(self, action: #selector(textFieldDidChange(_:)), for: .editingChanged)
signUpView.passwordTextField.addTarget(self, action: #selector(textFieldDidChange(_:)), for: .editingChanged)
signUpView.checkPasswordTextField.addTarget(self, action: #selector(textFieldDidChange(_:)), for: .editingChanged)
}
Expand All @@ -60,8 +61,8 @@ class SignUpFormViewController: UIViewController {

viewModel.onSignUpButtonState = { [weak self] isAvailable in
DispatchQueue.main.async {
self?.signUpView.bottomButtonView.button.isEnabled = isAvailable
self?.signUpView.bottomButtonView.button.backgroundColor = isAvailable ? .brandColor : .color171
self?.signUpView.bottomButtonView.isEnabled = isAvailable
self?.signUpView.bottomButtonView.backgroundColor = isAvailable ? .brandMain : .blackAC
}
}

Expand All @@ -86,9 +87,9 @@ class SignUpFormViewController: UIViewController {
viewModel.onEmailSendMessage = { [weak self] message, isAvailable in
DispatchQueue.main.async {
self?.updateStatus(label: self?.signUpView.emailErrorLabel, message: message, isAvailable: isAvailable, textField: self?.signUpView.emailTextField)
self?.signUpView.emailCheckButton.hideLoading()
self?.signUpView.authStack.isHidden = !isAvailable
if isAvailable == true {
self?.signUpView.emailCheckButton.updateTitle("인증요청 완료")
self?.signUpView.emailCheckButton.updateBackgroundColor(.color171)
self?.signUpView.emailCheckButton.isEnabled = isAvailable
}
Expand All @@ -109,7 +110,7 @@ class SignUpFormViewController: UIViewController {
// 타이머 업데이트
viewModel.onUpdateTimer = { [weak self] timeString in
DispatchQueue.main.async {
self?.signUpView.timer.text = timeString
self?.signUpView.timer.attributedText = UIFont.CustomFont.bodyP4(text: timeString, textColor: .error)
}
}
}
Expand All @@ -124,6 +125,13 @@ class SignUpFormViewController: UIViewController {
switch textField {
case signUpView.userNameTextField:
viewModel.checkUserNameValidation(userName: userName)
case signUpView.emailTextField:
signUpView.emailCheckButton.updateBackgroundColor(.brandMain)
signUpView.emailCheckButton.isEnabled = true
signUpView.authCheckButton.updateBackgroundColor(.brandMain)
signUpView.authCheckButton.isEnabled = true
viewModel.signUpBody.email = nil
signUpView.authCheckButton.updateTitle("확인")
case signUpView.passwordTextField:
viewModel.checkPasswordAvailability(password: pw)
case signUpView.checkPasswordTextField:
Expand All @@ -138,6 +146,7 @@ class SignUpFormViewController: UIViewController {
}

@objc func authRequestButtonTapped() {
signUpView.emailCheckButton.showLoading()
viewModel.checkEmailAvailability(email: signUpView.emailTextField.text ?? "")
}

Expand All @@ -146,7 +155,6 @@ class SignUpFormViewController: UIViewController {
}

@objc func startButtonTapped() {
print("회원가입완료버튼 눌림")
viewModel.signUp()
}

Expand All @@ -158,8 +166,12 @@ class SignUpFormViewController: UIViewController {
}

private func updateStatus(label: UILabel?, message: String, isAvailable: Bool, textField: UITextField?) {
label?.text = message
label?.textColor = isAvailable ? .brandMain : .error
textField?.layer.borderColor = isAvailable ? UIColor.blackD4.cgColor : UIColor.error.cgColor
label?.attributedText = UIFont.CustomFont.bodyP5(text: message, textColor: isAvailable ? .brandMain : .error)
if let customTF = textField as? CustomTextField {
// 조건이 맞지 않으면 error 상태를 유지하도록 설정
customTF.setErrorState(!isAvailable)
} else {
textField?.layer.borderColor = isAvailable ? UIColor.blackD4.cgColor : UIColor.error.cgColor
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ class SignUpViewModel {
switch result {
case .success:
self.signUpBody.email = self.email
self.timerHelper.stopTimer()
self.onEmailVerifyCodeMessage?(emailVerifySuccessMessage, true)
case .failure(let error):
self.onEmailVerifyCodeMessage?(error.localizedDescription, false)
Expand Down
60 changes: 16 additions & 44 deletions Where_Are_You/Presentation/Login/SingUp/Views/SignUpFormView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,13 @@ class SignUpFormView: UIView {
return view
}()

private let titleLabel = CustomLabel(UILabel_NotoSans: .bold, text: "아래 내용을 작성해주세요", textColor: .black22, fontSize: 22)
private let titleLabel = StandardLabel(UIFont: UIFont.CustomFont.titleH1(text: "아래 내용을 작성해주세요", textColor: .black22))

private let userNameLabel = CustomLabel(UILabel_NotoSans: .medium, text: "이름", textColor: .color51, fontSize: LayoutAdapter.shared.scale(value: 12))
private let userNameLabel = StandardLabel(UIFont: UIFont.CustomFont.bodyP5(text: "이름", textColor: .black22))

let userNameTextField = CustomTextField(placeholder: "이름")
// Utilities.inputContainerTextField(withPlaceholder: "이름")

let userNameErrorLabel: UILabel = {
let label = UILabel()
label.numberOfLines = 0
label.font = UIFontMetrics.default.scaledFont(for: UIFont.pretendard(NotoSans: .medium, fontSize: 12))
label.adjustsFontForContentSizeCategory = true
return label
}()
let userNameErrorLabel = StandardLabel(UIFont: UIFont.CustomFont.bodyP5(text: "", textColor: .error))

// 이름 + 이름tf
lazy var usernameStack: UIStackView = {
Expand All @@ -47,20 +40,13 @@ class SignUpFormView: UIView {
return stackView
}()

private let emailLabel = CustomLabel(UILabel_NotoSans: .medium, text: "이메일", textColor: .color51, fontSize: LayoutAdapter.shared.scale(value: 12))
private let emailLabel = StandardLabel(UIFont: UIFont.CustomFont.bodyP5(text: "이메일", textColor: .black22))

let emailTextField = CustomTextField(placeholder: "이메일")
// Utilities.inputContainerTextField(withPlaceholder: "이메일")

let emailCheckButton = CustomButton(title: "인증요청", backgroundColor: .brandColor, titleColor: .white, font: UIFont.pretendard(NotoSans: .medium, fontSize: 14))
let emailCheckButton = TitleButton(title: UIFont.CustomFont.button16(text: "인증요청", textColor: .white), backgroundColor: .brandMain, borderColor: nil)

let emailErrorLabel: UILabel = {
let label = UILabel()
label.numberOfLines = 0
label.font = UIFontMetrics.default.scaledFont(for: UIFont.pretendard(NotoSans: .medium, fontSize: 12))
label.adjustsFontForContentSizeCategory = true
return label
}()
let emailErrorLabel = StandardLabel(UIFont: UIFont.CustomFont.bodyP5(text: "", textColor: .error))

// 이메일 + 이메일tf + 이메일 중복버튼 + description
lazy var emailCheckStack: UIStackView = {
Expand All @@ -77,17 +63,10 @@ class SignUpFormView: UIView {
}()

let authCodeTextField = CustomTextField(placeholder: "인증코드")
// Utilities.inputContainerTextField(withPlaceholder: "인증코드")

let timer: UILabel = {
let label = UILabel()
label.textColor = .error
label.font = UIFontMetrics.default.scaledFont(for: UIFont.pretendard(NotoSans: .medium, fontSize: 14))
label.adjustsFontForContentSizeCategory = true
return label
}()
let timer = StandardLabel(UIFont: UIFont.CustomFont.bodyP5(text: "", textColor: .error))

let authCheckButton = CustomButton(title: "확인", backgroundColor: .brandColor, titleColor: .white, font: UIFont.pretendard(NotoSans: .medium, fontSize: 14))
let authCheckButton = TitleButton(title: UIFont.CustomFont.button16(text: "확인", textColor: .white), backgroundColor: .brandMain, borderColor: nil)

// 인증코드tf + 인증코드 확인버튼
lazy var authCheckStack: UIStackView = {
Expand All @@ -97,24 +76,17 @@ class SignUpFormView: UIView {
return stackView
}()

let authCodeErrorLabel: UILabel = {
let label = UILabel()
label.numberOfLines = 0
label.font = UIFontMetrics.default.scaledFont(for: UIFont.pretendard(NotoSans: .medium, fontSize: 12))
label.adjustsFontForContentSizeCategory = true
return label
}()
let authCodeErrorLabel = StandardLabel(UIFont: UIFont.CustomFont.bodyP5(text: "", textColor: .error))

lazy var authStack: UIStackView = {
let stackView = UIStackView(arrangedSubviews: [authCheckStack, authCodeErrorLabel])
stackView.axis = .vertical
return stackView
}()

let passwordLabel = CustomLabel(UILabel_NotoSans: .medium, text: "비밀번호", textColor: .color51, fontSize: LayoutAdapter.shared.scale(value: 12))
let passwordLabel = StandardLabel(UIFont: UIFont.CustomFont.bodyP5(text: "비밀번호", textColor: .black22))

let passwordTextField = CustomTextField(placeholder: "비밀번호")
// Utilities.inputContainerTextField(withPlaceholder: "비밀번호")

let passwordErrorLabel: UILabel = {
let label = UILabel()
Expand All @@ -125,7 +97,6 @@ class SignUpFormView: UIView {
}()

let checkPasswordTextField = CustomTextField(placeholder: "비밀번호 확인")
// Utilities.inputContainerTextField(withPlaceholder: "비밀번호 확인")

let checkPasswordErrorLabel: UILabel = {
let label = UILabel()
Expand Down Expand Up @@ -155,7 +126,7 @@ class SignUpFormView: UIView {
return stackView
}()

let bottomButtonView = BottomButtonView(title: "시작하기")
let bottomButtonView = TitleButton(title: UIFont.CustomFont.button18(text: "시작하기", textColor: .white), backgroundColor: .blackAC, borderColor: nil)

// MARK: - Lifecycle

Expand All @@ -174,8 +145,8 @@ class SignUpFormView: UIView {
authStack.isHidden = true
passwordTextField.isSecureTextEntry = true
checkPasswordTextField.isSecureTextEntry = true
bottomButtonView.button.updateBackgroundColor(.color171)
bottomButtonView.button.isEnabled = false
bottomButtonView.updateBackgroundColor(.color171)
bottomButtonView.isEnabled = false

emailTextField.keyboardType = .emailAddress
authCodeTextField.keyboardType = .numberPad
Expand Down Expand Up @@ -232,8 +203,9 @@ class SignUpFormView: UIView {

bottomButtonView.snp.makeConstraints { make in
make.centerX.equalToSuperview()
make.leading.equalToSuperview()
make.bottom.equalTo(safeAreaLayoutGuide.snp.bottom)
make.leading.equalToSuperview().inset(LayoutAdapter.shared.scale(value: 24))
make.bottom.equalTo(safeAreaLayoutGuide.snp.bottom).inset(LayoutAdapter.shared.scale(value: 24))
make.height.equalTo(LayoutAdapter.shared.scale(value: 48))
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class TermsAgreementView: UIView {
return view
}()

private let titleLabel = StandardLabel(UIFont: UIFont.CustomFont.titleH1(text: "회원가입에 필요한\n약관에 동의해주세요", textColor: .black22))
private let titleLabel = StandardLabel(UIFont: UIFont.CustomFont.titleH1(text: "회원가입에 필요한 \n약관에 동의해주세요", textColor: .black22))

private let agreeView: UIView = {
let view = UIView()
Expand Down
55 changes: 54 additions & 1 deletion Where_Are_You/Utils/Customs/CustomButton.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@ class TitleButton: UIButton {
private var buttonTitle: NSAttributedString
private var buttonBackgroundColor: UIColor
private var borderColor: CGColor?
private var savedTitle: NSAttributedString?

private var spinner: UIActivityIndicatorView = {
let indicator = UIActivityIndicatorView(style: .medium)
indicator.hidesWhenStopped = true
indicator.translatesAutoresizingMaskIntoConstraints = false
return indicator
}()

// MARK: - Initializer
init(title: NSAttributedString, backgroundColor: UIColor, borderColor: CGColor?) {
Expand All @@ -35,10 +43,27 @@ class TitleButton: UIButton {
self.borderColor = borderColor
super.init(frame: .zero)
setupButton()
setupSpinner()
}

// 초기화 시 스피너 추가
override init(frame: CGRect) {
// 기본값을 제공하여 초기화
self.buttonTitle = NSAttributedString(string: "")
self.buttonBackgroundColor = .clear
self.borderColor = nil
super.init(frame: frame)
setupButton()
setupSpinner()
}

required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
self.buttonTitle = NSAttributedString(string: "")
self.buttonBackgroundColor = .clear
self.borderColor = nil
super.init(coder: coder)
setupButton()
setupSpinner()
}

// MARK: - Setup Button
Expand Down Expand Up @@ -72,6 +97,34 @@ class TitleButton: UIButton {
self.buttonBackgroundColor = color
backgroundColor = color
}

private func setupSpinner() {
addSubview(spinner)
// 스피너를 버튼 중앙에 위치시킵니다.
NSLayoutConstraint.activate([
spinner.centerXAnchor.constraint(equalTo: self.centerXAnchor),
spinner.centerYAnchor.constraint(equalTo: self.centerYAnchor)
])
}

/// 로딩 상태 시작: 타이틀을 숨기고 스피너를 시작합니다.
func showLoading() {
if let currentTitle = self.attributedTitle(for: .normal) {
savedTitle = currentTitle
}
setTitle("", for: .normal)
spinner.startAnimating()
}

/// 로딩 상태 종료: 스피너를 멈추고 원래 타이틀을 복원합니다.
func hideLoading() {
spinner.stopAnimating()
// 저장해둔 타이틀이 있다면 복원, 없으면 기본값으로 설정
if let restoredTitle = savedTitle {
self.setAttributedTitle(restoredTitle, for: .normal)
}
savedTitle = nil
}
}

// MARK: - 추가 옵션버튼뷰(여러개)
Expand Down
Loading

0 comments on commit 3dcc65c

Please sign in to comment.