2

I have a custom View, and in this custom View I declared var isSelected: false that is gonna be toggle when taping on the view.

After I add two of those custom Views in my ViewController.

What I need is: When I select one of view, the other one is immediately deselected, so only one can be selected at the same time.

I don't have much knowledge about it, but I assume that with RxCocoa (or ideally RxSwift) it might be possible to set this isSelected variable of each view as an observable, and then in the subscription, set the other one to false once it turns true.

Help will be much appreciated, thank you in advance.

Cublax
  • 1,232
  • 1
  • 11
  • 20
  • 2
    It's even possible without RxSomething. Add a callback closure to the view(s) and call it when `isSelected` changed to true. Pass a reference to the view in the closure and deselect the other view respectively. Or use `NSKeyValueObservation`. – vadian May 27 '20 at 14:14
  • can you share some of the work that you have already done? – Nick May 27 '20 at 15:05

1 Answers1

1

I know what you are asking for seems like a reasonable idea, but it's not. Your isSelected boolean won't change state unless you specifically write code to make it change state. That begs the question, why is other code monitoring your view's isSelected boolean rather than the event that causes the boolean to change state? Why the middle man? Especially a middle-man that is part of your View system, not your Model.

The appropriate solution is to have an Observable in your model that is bound to your two views...

Better would be something like:

class CustomView: UIView {
    var isSelected: Bool = false
}

class Example {
    let viewA = CustomView()
    let viewB = CustomView()
    let disposeBag = DisposeBag()

    func example(model: Observable<Bool>) {
        disposeBag.insert(
            model.bind(to: viewA.rx.isSelected),
            model.map { !$0 }.bind(to: viewB.rx.isSelected)
        )
    }
}

extension Reactive where Base: CustomView {
    var isSelected: Binder<Bool> {
        Binder(base, binding: { view, isSelected in
            view.isSelected = isSelected
        })
    }
}
Daniel T.
  • 32,821
  • 6
  • 50
  • 72