How to subscribe on the value changed control event of a UISwitch Using Rxswift

rxswift controlevent
behaviorrelay rxswift
rxswift toggle
rxswift get value from observable
rxswift distinctuntilchanged
userdefaults rxswift
rxswift two way binding
rxswift button tap

I want to use Rxswift and not IBActions to solve my issue below,

I have a UISwitch and I want to subscribe to the value changed event in it,

I usually subscribe on Buttons using this manner

@IBOutlet weak var myButton: UIButton!


myButton
    .rx
    .tapGesture()
    .when(.recognized)
    .subscribe(onNext : {_ in /*do action here */})

Does anyone know how to subscribe to UISwitch control events?

Below are some caveats you would use for UISwitch:

 1. Make sure the event subscribes to unique changes so use distinctUntilChanged
 2. Rigorous switching the switch can cause unexpected behavior so use debounce.

 Example: 

anySwitch.rx
.isOn.changed //when state changed
.debounce(0.8, scheduler: MainScheduler.instance) //handle rigorous user switching
.distinctUntilChanged().asObservable() //take signal if state is different than before. This is optional depends on your use case
.subscribe(onNext:{[weak self] value in
            //your code
}).disposed(by: disposeBag)

Control Property skips events · Issue #471 · ReactiveX/RxSwift , I want to use Rxswift and not IBActions to solve my issue below,. I have a UISwitch and I want to subscribe to the value changed event in it,. I usually subscribe  As with UISlider, when the user manipulates the switch control (“flips” it) a value Changed event is generated, which results in the control (if properly configured) sending an action message. You can customize the appearance of the switch by changing the color used to tint the switch when it is on or off.

I found the answer Im looking for, in order to subscribe on and control event we should do the below :

@IBOutlet weak var mySwitch : UISwitch!

       mySwitch 
            .rx
            .controlEvent(.valueChanged)
            .withLatestFrom(mySwitch.rx.value)
            .subscribe(onNext : { bool in
                // this is the value of mySwitch
            })
            .disposed(by: disposeBag)

Toggle Component with RxSwift - Maciek Grzybowski, I want to use Rxswift and not IBActions to solve my issue below,. I have a UISwitch and I want to subscribe to the value changed event in it,. 6 How to subscribe on the value changed control event of a UISwitch Using Rxswift 5 Change ViewController from Tabbar View more network posts →

There are couple of ways to do that. But this one is how I usually do it: Try this out.

self.mySwitch.rx.isOn.subscribe { isOn in
            print(isOn)
        }.disposed(by: self.disposeBag)

I hope this helps.

EDIT:

Another would be subscribing to the value rx property of the UISwitch, like so:

mySwitch.rx.value.subscribe { (isOn) in
            print(isOn)
        }.disposed(by: self.disposeBag)

Now, as for your comment:

this worked for me thanks , but I preferred subscribing on the control event it self, not the value.

We could do this below, I'm not sure though if there's a better way than this. Since UISwitch is a UIControl object, you can subscribe to its .valueChanged event, like so:

    mySwitch.rx.controlEvent([.valueChanged]).subscribe { _ in
        print("isOn? : \(mySwitch.isOn)")
        }.disposed(by: self.disposeBag)

More info: https://developer.apple.com/documentation/uikit/uiswitch

RxSwift: UISwitch toggle back to initial State, used in ControlProperty can result in missing value change events from a control. The simplest example of this is a UISwitch's rx_value. Take the Observable value you’ve created and subscribe to it, updating the validity of the text field based on the incoming value. Add the resulting Disposable to the disposeBag . The code for the expiration date and CVV validation follows the sample pattern.

The following code works for me, building on prex's answer. Please feel free to correct or suggest any improvements.

RxSwift/RxCocoa 4.4, iOS 12, Xcode 10

private let _disposeBag = DisposeBag()

let viewModel: ViewModel ...
let switchControl: UIControl ...

let observable = switchControl
    .rx.isOn
    .changed   // We want user-initiated changes only.
    .distinctUntilChanged()
    .share(replay: 1, scope: .forever)

observable
    .subscribe(onNext: { [weak self] value in
        self?.viewModel.setSomeOption(value)
    })
    .disposed(by: _disposeBag)

In this example, we are notified when the user (and only the user) changes the state of the UISwitch. We then update viewModel.

In turn, any observers of the viewModel, will be told of the change of state, allowing them to update UI, etc.

e.g.

class ViewModel
{
    private var _someOption = BehaviorRelay(value: false)

    func setSomeOption(_ value: Bool) { _someOption.accept(value) }

    /// Creates and returns an Observable on the main thread.

    func observeSomeOption() -> Observable<Bool>
    {
        return _someOption
            .asObservable()
            .observeOn(MainScheduler())
    }
}

...

// In viewDidLoad()

    self.viewModel
        .observeSomeOption()
        .subscribe(onNext: { [weak self] value in
            self?.switchControl.isOn = value
            // could show/hide other UI here.
        })
        .disposed(by: _disposeBag)

See: https://stackoverflow.com/a/53479618/1452758

Как подписаться на измененное значение управляющего , List of toggle switches is widely present in mobile world. value: Driver<​ToggleValue> — when subscription is made, it emits .initial(Bool) means that the change was saved and UISwitch is synchronized with the storage. Before we present toggle's UI control on screen, we must know its default value. This special trick of a Driver allows us to wire a UIControl to an Observable's output without any manual call to subscribe(). Using a Driver. To use a driver, we’re going to modify our ViewController code a bit. We’ll remove the subscribe() call entirely, and use the Driver to drive() the UILabel’s text property instead.

Reactive programming with RxSwift, switchPermission.rx.value) .map { isOn in var newPermission = item As you already have in your view controller, all cells send an updated permission through the the permissions object will emit but it won't actually change state since it was I do it in the subscribe block, however this does not get called in the event of  If you set multiple values in one run loop block, it will only only emit value in the following run loop if the text value has changed. If we can somehow improve this behavior and make it even more consistent, that would be great, but I don't think it's significantly different then other rx_text behaviors, although I can see how emitting that programmatically changed value can be little confusing.

User MhmdRizk, Я хочу использовать Rxswift а не IBActions чтобы решить мою проблему У меня есть UISwitch и я хочу подписаться на событие изменения controlEvent(. withLatestFrom(mySwitch.rx.value) .subscribe(onNext : { bool in // this is the sure the event subscribes to unique changes so use distinctUntilChanged 2. The simplest example of this is a UISwitch's rx_value. When subscribing rx_value sends .Next(false) Send .Next(true) intto rx_value. rx_value correctly does not send an event. User flips switch. rx_value does NOT send .Next(false) even though the value of the control changed.

RxSwift offers more control over asynchronous code in your iOS In RxSwift an Event is just an Enumeration Type with 3 possible For example, it's very easy to use RxCocoa to subscribe to the state changes of a UISwitch  we need to deal with state changes reactively; the code is not testable at all. Time to meet our first guest. RxSwift. The component that will allow us to respond to changes reactively and write declarative code. What is Rx? One of the definitions is: ReactiveX is a library for composing asynchronous and event-based programs by using observable

Comments
  • Does yourSwitch.rx.value.changed.subscribe(onNext: ...) work?
  • I tried it now, and it didnt
  • this worked for me thanks , but I preferred subscribing on the control event it self, not the value
  • thanks for the effort bro, but I posted the solution and it worked by subscribe on the value changed event, check my answer