Skip to content

Commit

Permalink
Merge pull request #39 from Noostak/feat/NST-10/signUp
Browse files Browse the repository at this point in the history
[Feat/NST-10] #38 회원가입 화면 작성
  • Loading branch information
FpRaArNkK authored Feb 26, 2025
2 parents f66dbbd + 1e5f3f5 commit fc85203
Show file tree
Hide file tree
Showing 14 changed files with 674 additions and 186 deletions.
18 changes: 18 additions & 0 deletions Noostak_iOS/Noostak_iOS/Domain/UseCase/UserUseCase.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//
// UserUseCase.swift
// Noostak_iOS
//
// Created by 박민서 on 2/20/25.
//

import RxSwift

protocol UserUseCaseProtocol {
func validate(name: String) -> Observable<ValidationResult>
}

final class UserUseCase: UserUseCaseProtocol {
func validate(name: String) -> Observable<ValidationResult> {
return Observable.just(SignUpValidator.validate(name: name))
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//
// SignUpValidator.swift
// Noostak_iOS
//
// Created by 박민서 on 2/20/25.
//

import Foundation

struct SignUpValidator {
static func validate(name: String) -> ValidationResult {
// 1. 글자 수 제한 (1~10자)
guard (1...10).contains(name.count) else {
return .invalid(reason: "이름은 1~10자로 입력해야 합니다.")
}

// 2. 허용 문자: 영어 대소문자, 숫자, 한글, 홀자(한자)
let regex = "^[A-Za-z0-9가-힣]*$"
let predicate = NSPredicate(format: "SELF MATCHES %@", regex)

if !predicate.evaluate(with: name) {
return .invalid(reason: "띄어쓰기 및 특수문자는 사용할 수 없습니다.")
}

return .valid
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//
// ValidationResult.swift
// Noostak_iOS
//
// Created by 박민서 on 2/20/25.
//


enum ValidationResult {
case valid
case invalid(reason: String)
}
150 changes: 0 additions & 150 deletions Noostak_iOS/Noostak_iOS/Global/Components/AppColorTextField.swift

This file was deleted.

71 changes: 36 additions & 35 deletions Noostak_iOS/Noostak_iOS/Global/Components/AppThemeButton.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@ final class AppThemeButton: UIButton {
private let disposeBag = DisposeBag()
private let theme: AppThemeButton.Theme
private let title: String
private let _isEnabledRelay = BehaviorRelay<Bool>(value: false)

init(theme: Theme = .grayScale, title: String = "다음") {
self.theme = theme
self.title = title
super.init(frame: .zero)
setupUI()
updateUI(for: .disable)
updateUI(isEnabled: false)
bind()
}

required init?(coder: NSCoder) {
Expand All @@ -40,41 +42,23 @@ final class AppThemeButton: UIButton {
self.setTitleColor(theme.foregroundColor, for: .normal)
}

private func updateUI(for state: State) {
self.backgroundColor = theme.backgroundColor(state)
self.isEnabled = state.isEnabled
private func updateUI(isEnabled: Bool) {
self.backgroundColor = theme.backgroundColor(isEnabled)
self.isEnabled = isEnabled
}
}

// MARK: - Interface
extension AppThemeButton {
func bind(state: Observable<AppThemeButton.State>) {
state

private func bind() {
isEnabledRelay
.distinctUntilChanged()
.observe(on: MainScheduler.instance)
.subscribe(onNext: { [weak self] state in
self?.updateUI(for: state)
.subscribe(onNext: { [weak self] isEnabled in
self?.updateUI(isEnabled: isEnabled)
})
.disposed(by: disposeBag)
}
}

extension AppThemeButton {

/// 버튼의 활성/비활성 상태
enum State {
case able
case disable

var isEnabled: Bool {
switch self {
case .able:
return true
case .disable:
return false
}
}
}

/// 버튼의 컬러 웨이
enum Theme {
Expand All @@ -85,14 +69,31 @@ extension AppThemeButton {
return .white
}

func backgroundColor(_ state: AppThemeButton.State) -> UIColor {
switch state {

case .able:
return self == .colorScale ? .appBlue600 : .appGray900
case .disable:
return .appGray500
}
func backgroundColor(_ availability: Bool) -> UIColor {
return availability
? self == .colorScale ? .appBlue600 : .appGray900
: .appGray500
}
}
}

// MARK: - Interface
extension AppThemeButton {
var isEnabledRelay: BehaviorRelay<Bool> {
return _isEnabledRelay
}
}

// MARK: Rx Extension
extension Reactive where Base: AppThemeButton {
var isEnabled: ControlProperty<Bool> {
let isEnabledRelay = base.isEnabledRelay

return ControlProperty(
values: isEnabledRelay.asObservable(),
valueSink: Binder(base) { button, state in
button.isEnabledRelay.accept(state)
}
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ final class ProfileImagePicker: UIView {

cameraButton.do {
$0.setImage(.icnProfileCamera, for: .normal)
$0.isUserInteractionEnabled = true
$0.isUserInteractionEnabled = false
}
}

Expand Down
Loading

0 comments on commit fc85203

Please sign in to comment.