Search code examples
iosswiftrx-swiftreactivekit

How to bind array count to replace button image


I'm trying to observe array change and bind it to the image of the button.

if the array is empty. set picture of an empty cart.

else set image of a cart.

so what I did was :

let x = itemsArray.observeNext { [weak self] (v) in
    let image = v.source.isEmpty ? #imageLiteral(resourceName: "emptyCart") : #imageLiteral(resourceName: "cart")
    self?.orderItemsButton.setImage(image, for: .normal)
}

But if I do use this way I must dispose x in viewWillDisappear or something like that...

What is the right way to do it?


Solution

  • You can replace observation with a binding. In that case disposable is handled by the framework itself (ReactiveKit).

    All you need to do is this:

    itemsArray.bind(to: self) { me, array in
        let image = array.source.isEmpty ? #imageLiteral(resourceName: "emptyCart") : #imageLiteral(resourceName: "cart")
        me.orderItemsButton.setImage(image, for: .normal)
    }
    

    You can find more info about bindings in the documentation: https://github.com/ReactiveKit/ReactiveKit#bindings

    I would almost always recommend doing bind(to:) instead observeNext. It automatically handles weak self, disposing and also ensures that the object is updated on the correct thread.


    As a bonus, you can also solve this problem by mapping the array signal to an image signal and then binding that to the button (assuming you are using ReactiveKit+Bond).

    itemsArray
      .map { $0.source.isEmpty ? #imageLiteral(resourceName: "emptyCart") : #imageLiteral(resourceName: "cart") }
      .bind(to: orderItemsButton.reactive.image)