iOS/RxSwift

[RxSwift] RxSwift와 RxCocoa로 Toggle Button 구현하기

여성일 2024. 5. 2. 19:12
728x90
UIKit으로 구현하기
var isToggled: Bool = false // 버튼의 상태를 담고있는 변수

private lazy var toggleButton: UIButton = {
    let button = UIButton()
    button.backgroundColor = .clear
    button.setTitle("Off", for: .normal)
    button.setTitleColor(.black, for: .normal)
    button.addTarget(self, action: #selector(toggleButtonTapped), for: .touchUpInside)
    return button
}() // 버튼 생성

@objc func toggleButtonTapped() {
    isToggled.toggle()
    
    let title = isToggled ? "On" : "Off"
    toggleButton.setTitle(title, for: .normal)
}

가장 간단하고 단순한 방법이다. isToggled의 값을 통해 버튼의 상태를 추적하고, 버튼이 눌릴 때 isToggled를 토글하여 버튼의 제목을 업데이트 하는 코드이다.

 

var isToggled: Bool = false {
    didSet {
        // 토글 상태가 변경될 때 호출
        onUpdate()
    }
}

private lazy var toggleButton: UIButton = {
    let button = UIButton()
    button.backgroundColor = .clear
    button.setTitle("Off", for: .normal)
    button.setTitleColor(.black, for: .normal)
    button.addTarget(self, action: #selector(toggleButtonTapped), for: .touchUpInside)
    return button
}() // 버튼 생성

@objc func toggleButtonTapped() {
    isToggled.toggle()
}

func onUpdate() {
    let title = isToggled ? "On" : "Off"
    toggleButton.setTitle(title, for: .normal)
}

didSet 프로퍼티 옵저버는 isToggled의 값이 변경될 때마다 호출되어 onUpdate() 메소드를 실행한다. 

 

Rx로 구현하기
private let disposeBag = DisposeBag()

private let isToggled = BehaviorRelay<Bool>(value: false)

private lazy var toggleButton: UIButton = {
    let button = UIButton()
    button.backgroundColor = .clear
    button.setTitleColor(.black, for: .normal)
    return button
}() // 버튼 생성

func toggle() {
    isToggled
        .asObservable()
        .subscribe(onNext: { [weak self] toggled in
            self?.onUpdate(isToggled: toggled)
        })
        .disposed(by: disposeBag)
        
    toggleButton.rx.tap
       .withLatestFrom(isToggled)
       .map { !$0 }
       .bind(to: isToggled)
       .disposed(by: disposeBag)
}
    
func onUpdate(isToggled: Bool) {
    isToggled ? toggleButton.setTitle("On", for: .normal) : toggleButton.setTitle("Off", for: .normal)
}

toggleButton.rx.tap을 통해 UIButton의 tap 이벤트를 구독하고, 버튼이 탭 되면 이벤트가 발생한다. withLatestFrom 연산자를 통해 가장 최근의 토글 상태를 가져와 이를 map 메소드로 반전하여 반환한다. 반전 된 상태를 isToggle에 바인딩하여 토글 상태를 업데이트 한다. isToggled를 구독하고 있다가, 상태 변화가 감지되면 onUpdate 메소드를 실행하여 토글 상태에 따라 버튼의 title을 변경한다.