Как подписаться на измененное значение управляющего события UISwitch с помощью Rxswift - PullRequest
0 голосов
/ 19 ноября 2018

Я хочу использовать Rxswift, а не IBActions, чтобы решить мою проблему ниже,

У меня есть UISwitch, и я хочу подписаться на событие изменения значения в это,

Я обычно подписываюсь на кнопки таким образом

@IBOutlet weak var myButton: UIButton!


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

Кто-нибудь знает, как подписаться на UISwitch события управления?

Ответы [ 4 ]

0 голосов
/ 03 июля 2019

Следующий код работает для меня, основываясь на ответе прекса.Пожалуйста, не стесняйтесь исправлять или предлагать какие-либо улучшения.

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)

В этом примере мы уведомляемся, когда пользователь (и только пользователь)) изменяет состояние UISwitch.Затем мы обновляем viewModel.

. В свою очередь, всем наблюдателям viewModel будет сообщено об изменении состояния, что позволит им обновить пользовательский интерфейс и т. Д.

например

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)

См .: https://stackoverflow.com/a/53479618/1452758

0 голосов
/ 20 ноября 2018
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)
0 голосов
/ 20 ноября 2018

Я нашел ответ, который искал, чтобы подписаться и контролировать событие, мы должны сделать следующее:

@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)
0 голосов
/ 19 ноября 2018

Есть несколько способов сделать это. Но вот как я обычно это делаю: Попробуйте это.

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

Надеюсь, это поможет.

EDIT:

Другой подписался бы на свойство value rx UISwitch, например:

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

Теперь, что касается вашего комментария:

это сработало для меня, спасибо, но я предпочел подписаться на элемент управления событие само по себе, а не значение.

Мы могли бы сделать это ниже, хотя я не уверен, есть ли лучший способ, чем этот. Поскольку UISwitch является UIControl объектом, вы можете подписаться на его .valueChanged событие, например:

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

Подробнее: https://developer.apple.com/documentation/uikit/uiswitch

...