이용 약관 동의 같은 체크버튼 로직

홍석현·2022년 8월 18일
0

최종 결과물

회원 가입할 때 필수 조건에 대해서 모두 체크했을 경우에 버튼의 활성/비활성, 혹은 전체 버튼 선택에 대한 로직을 구현하는데 있어서 생각보다 까다로워서 공유합니다~!
더 좋은 로직, 혹은 좋은 의견 있으시면 댓글 부탁드려요!

버튼 타입 설정

일단 어떤 버튼을 눌렀는지 버튼 타입에 대해서 만들었습니다.

enum AgreementButtonType {
    case allAgree // 전체 동의 
    case requiredFirst // 필수 동의 첫번째
    case requiredSecond // 필수 동의 두번째
    case requiredThird // 필수 동의 세번째
    case notRequiredFourth // 선택 사항(마케팅 동의 같은)
}

Input

그래서 버튼을 눌렀을 때 해당 버튼 타입으로 변환해서 Input으로 가져왔습니다~!

// View 
Observable<AgreementButtonType>.merge([
	selectAllAgreement.rx.tap.map { _ in .allAgree },
	firstAgreement.rx.tap.map { _ in .requiredFirst },
	secondAgreement.rx.tap.map { _ in .requiredSecond },
	thirdAgreement.rx.tap.map { _ in .requiredThird },
	fourthAgreement.rx.tap.map { _ in .notRequiredFourth }
])
.bind(to: viewModel.input.buttonTapped)
.disposed(by: disposeBag)

// ViewModel
struct Input {
	let buttonTapped = PublishRelay<AgreementButtonType>()
}

뷰모델 로직

그 다음 각 버튼의 IsSelected 상태에 대한 BehaviorRelay로 만들어놓고 스트림을 연결했습니다. 그리고 Input으로 들어오는 버튼 타입에 대한 switch문으로 분기처리를 했어요.

let allAgreeIsSelected = BehaviorRelay<Bool>(value: false)
let requiredFirstIsSelected = BehaviorRelay<Bool>(value: false)
let requiredSecondIsSelected = BehaviorRelay<Bool>(value: false)
let requiredThirdIsSelected = BehaviorRelay<Bool>(value: false)
let notRequiredFourthIsSelected = BehaviorRelay<Bool>(value: false)
        
input.buttonTapped
	.bind { type in
		switch type {
		case .allAgree:
	        let preValue = allAgreeIsSelected.value
			[allAgreeIsSelected,
			requiredFirstIsSelected,
			requiredSecondIsSelected,
			requiredThirdIsSelected,
			notRequiredFourthIsSelected]
				.forEach { $0.accept(!preValue) }
		case .requiredFirst:
			requiredFirstIsSelected.accept(!requiredFirstIsSelected.value)
		case .requiredSecond:               
			requiredSecondIsSelected.accept(!requiredSecondIsSelected.value)
		case .requiredThird:                 
			requiredThirdIsSelected.accept(!requiredThirdIsSelected.value)
		case .notRequiredFourth:
			notRequiredFourthIsSelected.accept(!notRequiredFourthIsSelected.value)
			}
	}
	.disposed(by: disposeBag)

버튼들을 모두 선택했을 경우에 전체 버튼의 선택과 해제, 그리고 필수 버튼들을 모두 선택했을 때 다음으로 넘어가는 버튼의 활성화는 모두 combineLatest로 구현했습니다.

Observable.combineLatest(
            requiredFirstIsSelected,
            requiredSecondIsSelected,
            requiredThirdIsSelected,
            notRequiredFourthIsSelected)
{ $0 && $1 && $2 && $3 }
.bind(to: allAgreeIsSelected)
.disposed(by: disposeBag)

let nextButtonIsEnable = Observable.combineLatest(
	requiredFirstIsSelected,
	requiredSecondIsSelected,
	requiredThirdIsSelected)
	{ $0 && $1 && $2 }
profile
iOS 개발자입니다.

0개의 댓글