[RxSwift]Relay 버튼 활성화

구현해야하는 기능 → 특정 조건이 만족(아래 2가지 조건 True)이 되었을 때 

  • 닉네임 중복 체크 통과 → 해당 서버 API를 통해서 Bool 타입으로 값을 가져옴
  • 텍스트 뷰 → Text가 있는지 Bool 타입으로 체크

 

기존 구현

didSet을 통해 닉네임 중복에 대한 변수 isCheckNickname(Bool type)과 UITextView의 Text가 있는지에 대한 변수 isFillTextView가 true인지 guard문을 통해 체크를 해주어, 둘 다 true일 경우에는 버튼이 활성화되게 구현해주었다.

var isCheckNickname: Bool = false {
    didSet {
        guard isCheckNickname == true,
              isFillTextView == true
        else {
            // 버튼 비활성화 관련 구현부
        }
        // 버튼 활성화 관련 구현부
    }
}

var isFillTextView: Bool = false {
    didSet {
        guard isCheckNickname == true,
              isFillTextView == true
        else {
            // 버튼 비활성화 관련 구현부
        }
        // 버튼 활성화 관련 구현부
    }
}

당시 Relay에 대한 기능을 정확히 알지 못해 didSet으로 구현을 했었다. 코드 리뷰에서 굳이 didSet으로 구현한 이유에 대한 질문이 들어왔고, 다른 방법이 충분하다는 걸로 판단이 되어 RxSwift의 Bool type 변수를 이용해 UI에 어떻게 반영할지 고민했다.

 

개선 구현

Relay

우선 Relay에 대해 알아보았다. Subject와 비교하면 더 이해하기가 수월했다.
Subject.completed, .error의 이벤트가 발생하면 subscribe가 종료되는 반면 Relay.completed, .error를 발생하지 않고 Dispose되기 전까지 계속 작동하기 때문에 UI 등에서 사용하기 적절하다고 한다.

  • 기존 구현은 Bool 타입의 변수를 만들었다면, 개선 구현은 아래와 같이 Relay 변수로 만들어주었다.
private var isEnableNickname = BehaviorRelay<Bool>(value: false)
private var isFillBriefIntroduceText = BehaviorRelay<Bool>(value: false)

 

  • Relay 변수를 이용해 구현부에서 해당 조건이 만족하면 .accept를 이용해 Bool 타입 값을 할당해주었고, Driver의 combineLatest를 통해 두 객체가 true일 경우 버튼이 활성화 될 수 있도록 구현해주었다.
Driver.combinLatest(isEnableNickname.asDriver(),
                    isFillBriefIntroduceText.asDriver()) { $0 && $1 }
    .driver(onNext: { [weak self] in 
        guard let self = self else { return }
        self.changeNextButtonUI(self.nextButton, $0)
    })
    .disposed(by: disposeBag)

 

'iOS_Swift.zip' 카테고리의 다른 글

[RxSwift]UITextField 정규식  (0) 2022.09.10
[Swift]SnapKit + Then CollectionView Cell Size  (0) 2022.09.10
[Swift]Status Bar 색상 변겅  (0) 2022.04.21
[iOS]Strong과 weak 참조 방식  (0) 2022.02.27
[iOS]Protocol  (0) 2022.02.20