082_Rx(Input, Output)+MVVM
2022. 11. 1. 20:26ㆍSeSAC/수업정리
-. 뷰모델을 통해 UI로직과 비지니스 로직을 분리하면 객체, 이벤트가 많아졌을때 쉽게 확인 할 수 있다. 이 때 Input, Output으로 데이터 흐름을 구분 할 수 있다.
-. VC->VM : Input(버튼탭, 텍스트필드 입력하는 텍스트 등), VM->VC : Output(뷰 상태, 텍스트, 화면전환, 얼럿 등)
-. Input, Output 사용 전에는 뷰컨트롤러에서 이벤트를 처리했지만 Input을 사용해서 관찰대상이 되는 이벤트의 처리를 뷰모델에 전달하고, 뷰모델에서는 Output을 사용해서 연산을 적용한 이벤트를 뷰컨트롤러에 전달한다.(뷰컨틀롤러에서는 메서드의 반환값을 통해 값에 접근할 수 있음 ex.뷰컨트롤러에서 transform의 반환값인 Output구조체의 매개변수에 접근)
Input, Output 사용 전
-. 뷰모델
class ValidationViewModel {
let validText = BehaviorRelay(value: "닉네임은 최소 8자 이상 필요합니다")
}
-. 뷰컨트롤러
viewModel.validText
.asDriver() //relay짝궁은 DRIVER
.drive(validationLabel.rx.text)
.disposed(by: disposeBag)
let validation = nameTextField.rx.text //String?타입
.orEmpty //String타입
.map { $0.count >= 8 } //Bool타입
.share() //subject 내부에 share가 있기 때문에 subject에서는 share 따로 안써도 됨
validation
.bind(to: stepButton.rx.isEnabled, validationLabel.rx.isHidden)
.disposed(by: disposeBag)
validation
.withUnretained(self)
.bind { (vc, value) in
let color: UIColor = value ? .systemPink : .lightGray
self.stepButton.backgroundColor = color
}
.disposed(by: disposeBag)
Input, Output 사용 후
-. 뷰모델
class ValidationViewModel {
let validText = BehaviorRelay(value: "닉네임은 최소 8자 이상 필요합니다")
struct Input {
let text: ControlProperty<String?> //let validation = nameTextField.rx.text에서 text타입인 ControlProperty로 프로퍼티 생성
let tap: ControlEvent<Void> //stepButton.rx.tap
}
struct Output {
let validation: Observable<Bool> //validation에 대한 연산을 거치고 뷰컨트롤러로 전달할 값의 타입을 가진 프로퍼티 생성
let tap: ControlEvent<Void> //input, output 동일
let text: Driver<String> //viewModel.validText에서 구독할 대상의 타입가진 프로퍼티 생성
}
//input->output 바꿔주는 메서드
func transform(input: Input) -> Output{
let valid = input.text //let input = ValidationViewModel.Input(text: nameTextField.rx.text, tap: stepButton.rx.tap)에서 input을 통해 text에 접근할 수 있으므로 let validation = nameTextField.rx.text과 동일
.orEmpty //String타입
.map { $0.count >= 8 } //Bool타입
.share() //subject 내부에 share가 있기 때문에 subject에서는 share 따로 안써도 됨
let text = validText.asDriver() //asDriver까지 연산메서드에서 처리
return Output(validation: valid, tap: input.tap, text: text)
}
}
-. 뷰컨트롤러
let input = ValidationViewModel.Input(text: nameTextField.rx.text, tap: stepButton.rx.tap) //텍스트필드 입력내용을 뷰모델로 보냄
let output = viewModel.transform(input: input) //
output.text
.drive(validationLabel.rx.text)
.disposed(by: disposeBag)
output.validation
.bind(to: stepButton.rx.isEnabled, validationLabel.rx.isHidden)
.disposed(by: disposeBag)
output.validation
.withUnretained(self)
.bind { (vc, value) in
let color: UIColor = value ? .systemPink : .lightGray
self.stepButton.backgroundColor = color
}
.disposed(by: disposeBag)
'SeSAC > 수업정리' 카테고리의 다른 글
083_Network(signup, login) (0) | 2022.11.02 |
---|---|
43_Login, Lotto Examples(Observable+MVVM) (0) | 2022.10.25 |
074_MVVM+DiffableDataSource(숫자입력, 검색이미지) (0) | 2022.10.21 |
072_UICollectionLayoutListConfiguration(테이블뷰스타일 컬렉션뷰) (0) | 2022.10.18 |
032_for-in, foreach 알아보기 (0) | 2022.08.17 |